Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
549
cde/lib/tt/bin/tttar/tttar_api.C
Normal file
549
cde/lib/tt/bin/tttar/tttar_api.C
Normal file
@@ -0,0 +1,549 @@
|
||||
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
||||
//%% $XConsortium: tttar_api.C /main/4 1995/10/20 16:59:54 rswiston $
|
||||
/*
|
||||
* tttar_api.cc - ToolTalk object archiving interface functions.
|
||||
*
|
||||
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#if defined(__osf__)
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#ifndef USL
|
||||
#include <osfcn.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#include "api/c/api_api.h"
|
||||
#include "api/c/tt_c.h"
|
||||
#include "util/tt_path.h"
|
||||
#include "util/tt_gettext.h"
|
||||
#include "tttar_utils.h"
|
||||
#include "tttar_file_utils.h"
|
||||
#include "tttar_spec.h"
|
||||
#include "tttar_api.h"
|
||||
|
||||
/*
|
||||
* Type definitions
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
|
||||
// Number of buckets in a hash table of interesting specs in an archive.
|
||||
#define SPEC_MAP_SIZE 1000
|
||||
|
||||
/*
|
||||
* Private functions
|
||||
*/
|
||||
static bool_t path_lstt_archive(
|
||||
_Tt_string path,
|
||||
int verbosity,
|
||||
XDR *xdrs );
|
||||
bool_t dearchive_this_path(
|
||||
char *path, void *ppaths_to_extract );
|
||||
static Tt_filter_action gather_specs( const char *spec_id, void *,
|
||||
void *specs);
|
||||
|
||||
/*
|
||||
* pathlist_lstt_archive() - Archive the LS/TT objects in the given paths.
|
||||
*/
|
||||
bool_t
|
||||
pathlist_lstt_archive(
|
||||
_Tt_string_list_ptr paths,
|
||||
bool_t recurse,
|
||||
bool_t follow_symlinks,
|
||||
int verbosity,
|
||||
XDR *xdrs )
|
||||
{
|
||||
_Tt_string_list_ptr realpaths2tar;
|
||||
Object_kind obj_kind;
|
||||
_Tt_string_list_ptr paths_copy(new _Tt_string_list);
|
||||
_Tt_string_list_cursor path_cursor( paths );
|
||||
while (path_cursor.next()) {
|
||||
paths_copy->append( *path_cursor );
|
||||
}
|
||||
|
||||
bool_t need_preliminary_pass = follow_symlinks && recurse;
|
||||
realpaths2tar = realtrees( paths_copy, need_preliminary_pass );
|
||||
|
||||
obj_kind = VERSION_NUM;
|
||||
int version = CURRENT_ARCHIVE_VERSION;
|
||||
if ( (! xdr_enum( xdrs, (enum_t *)&obj_kind ))
|
||||
|| (! xdr_int( xdrs, &version )))
|
||||
{
|
||||
fprintf( stderr, "%s: ! xdr_enum() || ! xdr_int()\n",
|
||||
(char *)our_process_name );
|
||||
return FALSE;
|
||||
}
|
||||
while (! paths_copy->is_empty()) {
|
||||
_Tt_string_list_ptr children;
|
||||
_Tt_string path( paths_copy->top() );
|
||||
|
||||
paths_copy->pop();
|
||||
if (! path_lstt_archive( path, verbosity, xdrs ))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (recurse) {
|
||||
children = _tt_dir_entries( path, follow_symlinks );
|
||||
children->append_destructive( paths_copy );
|
||||
paths_copy = children;
|
||||
}
|
||||
}
|
||||
obj_kind = ARCHIVE_END;
|
||||
if (! xdr_enum( xdrs, (enum_t *)&obj_kind )) {
|
||||
fprintf( stderr, "%s: ! xdr_enum()\n",
|
||||
(char *)our_process_name );
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
} /* pathlist_lstt_archive() */
|
||||
|
||||
/*
|
||||
* pathlist_lstt_dearchive() - Extract the LS/TT objects of the given paths.
|
||||
* If no paths are given, extract everything in the archive.
|
||||
*/
|
||||
bool_t
|
||||
pathlist_lstt_dearchive(
|
||||
_Tt_string_list_ptr paths_to_extract,
|
||||
Lstar_string_map_list_ptr renamings,
|
||||
_Tt_string where_to_dearchive,
|
||||
bool_t preserve__props,
|
||||
int verbosity,
|
||||
XDR *xdrs )
|
||||
{
|
||||
_Tt_string last_path;
|
||||
char *this_path = NULL;
|
||||
int num_specs = 0;
|
||||
int num_links = 0;
|
||||
bool_t last_path_valid = FALSE;
|
||||
Object_kind obj_kind = NO_KIND;
|
||||
Lstar_string_map_table_ptr spec_map;
|
||||
int mem_mark = tt_mark();
|
||||
|
||||
spec_map = new Lstar_string_map_table(Lstar_string_map_old_string,
|
||||
SPEC_MAP_SIZE );
|
||||
do {
|
||||
bool_t just_dearchived_spec = FALSE;
|
||||
bool_t just_dearchived_link = FALSE;
|
||||
|
||||
if (! xdr_enum( xdrs, (enum_t *)&obj_kind )) {
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 7, 4,
|
||||
"%s: Could not read object kind "
|
||||
"from archive stream.\n"),
|
||||
(char *)our_process_name );
|
||||
return FALSE;
|
||||
}
|
||||
switch (obj_kind) {
|
||||
case VERSION_NUM:
|
||||
int version;
|
||||
if (! xdr_int( xdrs, &version)) {
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 7, 5,
|
||||
"%s: Could not read archive ver"
|
||||
"sion from archive stream.\n"),
|
||||
(char *)our_process_name );
|
||||
return FALSE;
|
||||
}
|
||||
if (version != CURRENT_ARCHIVE_VERSION) {
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 7, 6,
|
||||
"%s: Found archive version %d, "
|
||||
"but expected version %d.\n"),
|
||||
(char *)our_process_name, version,
|
||||
CURRENT_ARCHIVE_VERSION );
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case SPEC:
|
||||
char *old_spec_id;
|
||||
char *new_spec_id;
|
||||
Tt_status err;
|
||||
|
||||
old_spec_id = NULL;
|
||||
new_spec_id = NULL;
|
||||
err = TT_OK;
|
||||
|
||||
if (! spec_dearchive( &old_spec_id, &new_spec_id,
|
||||
&this_path, renamings,
|
||||
(char *)where_to_dearchive,
|
||||
preserve__props,
|
||||
dearchive_this_path,
|
||||
(void *)&paths_to_extract,
|
||||
verbosity,
|
||||
xdrs, &err ))
|
||||
{
|
||||
my_tt_release( mem_mark );
|
||||
return FALSE;
|
||||
}
|
||||
if (new_spec_id != NULL) {
|
||||
Lstar_string_map_ptr m = new Lstar_string_map;
|
||||
|
||||
m->old_string_set( old_spec_id );
|
||||
m->new_string_set( new_spec_id );
|
||||
m->extra_set( this_path );
|
||||
spec_map->insert( m );
|
||||
num_specs++;
|
||||
just_dearchived_spec = TRUE;
|
||||
}
|
||||
break;
|
||||
case ARCHIVE_END:
|
||||
break;
|
||||
case NO_KIND:
|
||||
default:
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 7, 7,
|
||||
"%s: found object of unknown kind "
|
||||
"%d in archive.\n"),
|
||||
(char *)our_process_name, (int)obj_kind );
|
||||
return FALSE;
|
||||
}
|
||||
if (verbosity && ( (last_path != this_path)
|
||||
|| (obj_kind == ARCHIVE_END)))
|
||||
{
|
||||
if (last_path_valid) {
|
||||
if (just_dearchived_spec) {
|
||||
num_specs--;
|
||||
} else if (just_dearchived_link) {
|
||||
num_links--;
|
||||
}
|
||||
if (verbosity > 1) {
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
if ( (num_specs > 0) || (num_links > 0)) {
|
||||
fprintf( stderr, "x %s %d %s\n",
|
||||
(char *)last_path, num_specs,
|
||||
( num_specs == 1
|
||||
? "spec" : "specs" ));
|
||||
}
|
||||
num_specs = 0;
|
||||
num_links = 0;
|
||||
if (just_dearchived_spec) {
|
||||
num_specs = 1;
|
||||
} else if (just_dearchived_link) {
|
||||
num_links = 1;
|
||||
}
|
||||
}
|
||||
last_path = this_path;
|
||||
if (! last_path_valid) {
|
||||
last_path_valid = TRUE;
|
||||
}
|
||||
}
|
||||
} while (obj_kind != ARCHIVE_END);
|
||||
my_tt_release( mem_mark );
|
||||
return TRUE;
|
||||
|
||||
} /* pathlist_lstt_dearchive() */
|
||||
|
||||
/*
|
||||
* pathlist_lstt_archive_list() - List the LS/TT objects of the given paths.
|
||||
* If no paths are given, list everything in the archive.
|
||||
*/
|
||||
bool_t
|
||||
pathlist_lstt_archive_list(
|
||||
_Tt_string_list_ptr paths_to_list,
|
||||
int verbosity,
|
||||
XDR *xdrs )
|
||||
{
|
||||
_Tt_string last_path;
|
||||
_Tt_string this_path;
|
||||
int num_specs = 0;
|
||||
int num_links = 0;
|
||||
bool_t last_path_valid = FALSE;
|
||||
Object_kind obj_kind = NO_KIND;
|
||||
Lstar_string_map_table_ptr spec_map;
|
||||
int mem_mark = tt_mark();
|
||||
|
||||
spec_map = new Lstar_string_map_table(Lstar_string_map_old_string,
|
||||
SPEC_MAP_SIZE );
|
||||
do {
|
||||
Lstar_spec spec;
|
||||
|
||||
if (! xdr_enum( xdrs, (enum_t *)&obj_kind )) {
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 7, 8,
|
||||
"%s: Could not read object kind "
|
||||
"from archive stream.\n"),
|
||||
(char *)our_process_name );
|
||||
return FALSE;
|
||||
}
|
||||
switch (obj_kind) {
|
||||
case VERSION_NUM:
|
||||
int version;
|
||||
if (! xdr_int( xdrs, &version)) {
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 7, 9,
|
||||
"%s: Could not read archive ver"
|
||||
"sion from archive stream.\n"),
|
||||
(char *)our_process_name );
|
||||
return FALSE;
|
||||
}
|
||||
if (version != CURRENT_ARCHIVE_VERSION) {
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 7, 10,
|
||||
"%s: Found archive version %d, "
|
||||
"but expected version %d.\n"),
|
||||
(char *)our_process_name, version,
|
||||
CURRENT_ARCHIVE_VERSION );
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case SPEC:
|
||||
if (! spec.xdr(xdrs)) {
|
||||
my_tt_release( mem_mark );
|
||||
return FALSE;
|
||||
}
|
||||
if (dearchive_this_path( (char *)spec.path(),
|
||||
&paths_to_list ))
|
||||
{
|
||||
Lstar_string_map_ptr m = new Lstar_string_map;
|
||||
|
||||
/*
|
||||
* Insert it into this "map" just so that
|
||||
* we can use the map to figure out if
|
||||
* a given link counts under paths_to_list.
|
||||
*/
|
||||
m->old_string_set( spec.id() );
|
||||
m->extra_set( spec.path() );
|
||||
spec_map->insert( m );
|
||||
this_path = spec.path();
|
||||
num_specs++;
|
||||
if (verbosity > 1) {
|
||||
spec.print( stdout );
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case ARCHIVE_END:
|
||||
break;
|
||||
case NO_KIND:
|
||||
default:
|
||||
fprintf( stderr,
|
||||
catgets(_ttcatd, 7, 11,
|
||||
"%s: found object of unknown kind "
|
||||
"%d in archive.\n"),
|
||||
(char *)our_process_name, (int)obj_kind );
|
||||
return FALSE;
|
||||
}
|
||||
if ( (last_path != this_path)
|
||||
|| (obj_kind == ARCHIVE_END))
|
||||
{
|
||||
if (last_path_valid) {
|
||||
if (obj_kind == SPEC) {
|
||||
num_specs--;
|
||||
} else if (obj_kind == SUN_LINK) {
|
||||
num_links--;
|
||||
}
|
||||
printf( "%s %d %s\n",
|
||||
(char *)last_path, num_specs,
|
||||
(num_specs == 1 ? "spec" : "specs" ));
|
||||
num_specs = 0;
|
||||
num_links = 0;
|
||||
if (obj_kind == SPEC) {
|
||||
num_specs = 1;
|
||||
} else if (obj_kind == SUN_LINK) {
|
||||
num_links = 1;
|
||||
}
|
||||
}
|
||||
last_path = this_path;
|
||||
if (! last_path_valid) {
|
||||
last_path_valid = TRUE;
|
||||
}
|
||||
}
|
||||
} while (obj_kind != ARCHIVE_END);
|
||||
my_tt_release( mem_mark );
|
||||
return TRUE;
|
||||
|
||||
} /* pathlist_lstt_archive_list() */
|
||||
|
||||
/*
|
||||
* path_lstt_archive() - Archive the specs on the given path.
|
||||
*/
|
||||
static bool_t
|
||||
path_lstt_archive(
|
||||
_Tt_string path,
|
||||
int verbosity,
|
||||
XDR *xdrs )
|
||||
{
|
||||
_Tt_string_list *specs;
|
||||
Object_kind obj_kind;
|
||||
int num_specs_archived = 0;
|
||||
int num_links_archived = 0;
|
||||
bool_t val2return = TRUE;
|
||||
|
||||
specs = new _Tt_string_list;
|
||||
note_err( tt_file_objects_query( (char *)path, gather_specs, NULL, specs ));
|
||||
if (IS_TT_ERR(err_noted)) {
|
||||
delete specs;
|
||||
return TRUE;
|
||||
}
|
||||
while (! specs->is_empty()) {
|
||||
_Tt_string spec = specs->top();
|
||||
Tt_status tt_err;
|
||||
|
||||
obj_kind = SPEC;
|
||||
specs->pop();
|
||||
if (! xdr_enum( xdrs, (enum_t *)&obj_kind )) {
|
||||
fprintf( stderr, "%s: ! xdr_enum()\n",
|
||||
(char *)our_process_name );
|
||||
val2return = FALSE;
|
||||
break;
|
||||
}
|
||||
if (! spec_archive( (char *)spec, (char *)path, verbosity,
|
||||
xdrs, &tt_err ))
|
||||
{
|
||||
val2return = FALSE;
|
||||
break;
|
||||
}
|
||||
num_specs_archived++;
|
||||
}
|
||||
if ((verbosity && num_specs_archived > 0 ) || (verbosity > 1)) {
|
||||
if (verbosity > 1) {
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
fprintf( stderr, "a %s: %d %s\n", (char *)path,
|
||||
num_specs_archived,
|
||||
((num_specs_archived == 1) ? "spec" : "specs" ));
|
||||
}
|
||||
delete specs;
|
||||
return val2return;
|
||||
|
||||
} /* path_lstt_archive() */
|
||||
|
||||
|
||||
/*
|
||||
* spec_archive() - Archive a spec onto the given XDR stream.
|
||||
*/
|
||||
bool_t
|
||||
spec_archive( char *id, char *path, int verbosity, XDR *xdrs, Tt_status *err )
|
||||
{
|
||||
_Tt_string _path( path );
|
||||
_Tt_string _id( id );
|
||||
|
||||
*err = TT_OK;
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
Lstar_spec spec( _id, _path );
|
||||
|
||||
*err = spec.read_self();
|
||||
if (IS_TT_ERR(*err)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (! spec.xdr(xdrs)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (verbosity > 1) {
|
||||
spec.print( stderr );
|
||||
}
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
} /* spec_archive() */
|
||||
|
||||
/*
|
||||
* spec_dearchive() - Recreate a spec that was archived on this XDR stream.
|
||||
*/
|
||||
bool_t
|
||||
spec_dearchive(
|
||||
char **old_spec_id_ptr,
|
||||
char **new_spec_id_ptr,
|
||||
char **path_as_archived,
|
||||
Lstar_string_map_list_ptr renamings,
|
||||
char *where_to_create,
|
||||
bool_t preserve__props,
|
||||
bool_t (*dearchive_this_path)(char *, void *),
|
||||
void *context,
|
||||
int verbosity,
|
||||
XDR *xdrs,
|
||||
Tt_status *err )
|
||||
{
|
||||
_Tt_string where( where_to_create );
|
||||
|
||||
*err = TT_OK;
|
||||
*old_spec_id_ptr = NULL;
|
||||
*new_spec_id_ptr = NULL;
|
||||
*path_as_archived = NULL;
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
return FALSE;
|
||||
} else if (xdrs->x_op == XDR_DECODE) {
|
||||
Lstar_spec spec;
|
||||
_Tt_string path;
|
||||
|
||||
if (! spec.xdr(xdrs)) {
|
||||
return FALSE;
|
||||
}
|
||||
*old_spec_id_ptr = _tt_strdup( spec.id() );
|
||||
*path_as_archived = _tt_strdup( spec.path() );
|
||||
path = spec.path();
|
||||
if ( (dearchive_this_path == NULL)
|
||||
|| (dearchive_this_path( (char *)path, context )))
|
||||
{
|
||||
_Tt_string _new_name = new_name( spec.path(),
|
||||
renamings );
|
||||
if (_new_name.len() > 0) {
|
||||
if (verbosity > 2) {
|
||||
fprintf( stderr, "%s => ",
|
||||
(char *)spec.path() );
|
||||
}
|
||||
spec.path_set( _new_name );
|
||||
if (verbosity > 2) {
|
||||
fprintf( stderr, "%s\n",
|
||||
(char *)spec.path() );
|
||||
}
|
||||
}
|
||||
*new_spec_id_ptr =
|
||||
spec.write_self( where, preserve__props, err );
|
||||
if (! IS_TT_ERR(*err) && (verbosity > 1)) {
|
||||
spec.print( stdout );
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
} /* spec_dearchive() */
|
||||
|
||||
|
||||
/*
|
||||
* dearchive_this_path() - Should we extract this <path> from its archive?
|
||||
*
|
||||
* Returns true if *ppaths_to_extract is an empty list.
|
||||
*/
|
||||
bool_t
|
||||
dearchive_this_path( char *path, void *ppaths_to_extract )
|
||||
{
|
||||
_Tt_string_list_ptr paths;
|
||||
_Tt_string _path( path );
|
||||
|
||||
if (ppaths_to_extract == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
paths = *(_Tt_string_list_ptr *)ppaths_to_extract;
|
||||
if (paths->count() <= 0) {
|
||||
return TRUE;
|
||||
}
|
||||
return is_child_in( _path, paths );
|
||||
|
||||
} /* dearchive_this_path() */
|
||||
|
||||
/*
|
||||
* gather_specs()
|
||||
*/
|
||||
static Tt_filter_action
|
||||
gather_specs( const char *spec_id, void *, void *specs )
|
||||
{
|
||||
_Tt_string id = spec_id;
|
||||
((_Tt_string_list *)specs)->push( id );
|
||||
return TT_FILTER_CONTINUE;
|
||||
}
|
||||
Reference in New Issue
Block a user