2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 //%% (c) Copyright 1993, 1994 Hewlett-Packard Company
24 //%% (c) Copyright 1993, 1994 International Business Machines Corp.
25 //%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
26 //%% (c) Copyright 1993, 1994 Novell, Inc.
27 //%% $XConsortium: tttar_api.C /main/4 1995/10/20 16:59:54 rswiston $
29 * tttar_api.cc - ToolTalk object archiving interface functions.
31 * Copyright (c) 1990 by Sun Microsystems, Inc.
36 #if defined(__osf__) || defined(linux) || defined(CSRG_BASED)
43 #include <sys/param.h>
44 #include "api/c/api_api.h"
45 #include "api/c/tt_c.h"
46 #include "util/tt_path.h"
47 #include "util/tt_gettext.h"
48 #include "tttar_utils.h"
49 #include "tttar_file_utils.h"
50 #include "tttar_spec.h"
51 #include "tttar_api.h"
62 // Number of buckets in a hash table of interesting specs in an archive.
63 #define SPEC_MAP_SIZE 1000
68 static bool_t path_lstt_archive(
72 bool_t dearchive_this_path(
73 char *path, void *ppaths_to_extract );
74 static Tt_filter_action gather_specs( const char *spec_id, void *,
78 * pathlist_lstt_archive() - Archive the LS/TT objects in the given paths.
81 pathlist_lstt_archive(
82 _Tt_string_list_ptr paths,
84 bool_t follow_symlinks,
88 _Tt_string_list_ptr realpaths2tar;
90 _Tt_string_list_ptr paths_copy(new _Tt_string_list);
91 _Tt_string_list_cursor path_cursor( paths );
92 while (path_cursor.next()) {
93 paths_copy->append( *path_cursor );
96 bool_t need_preliminary_pass = follow_symlinks && recurse;
97 realpaths2tar = realtrees( paths_copy, need_preliminary_pass );
99 obj_kind = VERSION_NUM;
100 int version = CURRENT_ARCHIVE_VERSION;
101 if ( (! xdr_enum( xdrs, (enum_t *)&obj_kind ))
102 || (! xdr_int( xdrs, &version )))
104 fprintf( stderr, "%s: ! xdr_enum() || ! xdr_int()\n",
105 (char *)our_process_name );
108 while (! paths_copy->is_empty()) {
109 _Tt_string_list_ptr children;
110 _Tt_string path( paths_copy->top() );
113 if (! path_lstt_archive( path, verbosity, xdrs ))
118 children = _tt_dir_entries( path, follow_symlinks );
119 children->append_destructive( paths_copy );
120 paths_copy = children;
123 obj_kind = ARCHIVE_END;
124 if (! xdr_enum( xdrs, (enum_t *)&obj_kind )) {
125 fprintf( stderr, "%s: ! xdr_enum()\n",
126 (char *)our_process_name );
131 } /* pathlist_lstt_archive() */
134 * pathlist_lstt_dearchive() - Extract the LS/TT objects of the given paths.
135 * If no paths are given, extract everything in the archive.
138 pathlist_lstt_dearchive(
139 _Tt_string_list_ptr paths_to_extract,
140 Lstar_string_map_list_ptr renamings,
141 _Tt_string where_to_dearchive,
142 bool_t preserve__props,
146 _Tt_string last_path;
147 char *this_path = NULL;
150 bool_t last_path_valid = FALSE;
151 Object_kind obj_kind = NO_KIND;
152 Lstar_string_map_table_ptr spec_map;
153 int mem_mark = tt_mark();
155 spec_map = new Lstar_string_map_table(Lstar_string_map_old_string,
158 bool_t just_dearchived_spec = FALSE;
159 bool_t just_dearchived_link = FALSE;
161 if (! xdr_enum( xdrs, (enum_t *)&obj_kind )) {
163 catgets(_ttcatd, 7, 4,
164 "%s: Could not read object kind "
165 "from archive stream.\n"),
166 (char *)our_process_name );
172 if (! xdr_int( xdrs, &version)) {
174 catgets(_ttcatd, 7, 5,
175 "%s: Could not read archive ver"
176 "sion from archive stream.\n"),
177 (char *)our_process_name );
180 if (version != CURRENT_ARCHIVE_VERSION) {
182 catgets(_ttcatd, 7, 6,
183 "%s: Found archive version %d, "
184 "but expected version %d.\n"),
185 (char *)our_process_name, version,
186 CURRENT_ARCHIVE_VERSION );
199 if (! spec_dearchive( &old_spec_id, &new_spec_id,
200 &this_path, renamings,
201 (char *)where_to_dearchive,
204 (void *)&paths_to_extract,
208 my_tt_release( mem_mark );
211 if (new_spec_id != NULL) {
212 Lstar_string_map_ptr m = new Lstar_string_map;
214 m->old_string_set( old_spec_id );
215 m->new_string_set( new_spec_id );
216 m->extra_set( this_path );
217 spec_map->insert( m );
219 just_dearchived_spec = TRUE;
227 catgets(_ttcatd, 7, 7,
228 "%s: found object of unknown kind "
230 (char *)our_process_name, (int)obj_kind );
233 if (verbosity && ( (last_path != (const char *)this_path)
234 || (obj_kind == ARCHIVE_END)))
236 if (last_path_valid) {
237 if (just_dearchived_spec) {
239 } else if (just_dearchived_link) {
243 fprintf( stderr, "\n" );
245 if ( (num_specs > 0) || (num_links > 0)) {
246 fprintf( stderr, "x %s %d %s\n",
247 (char *)last_path, num_specs,
249 ? "spec" : "specs" ));
253 if (just_dearchived_spec) {
255 } else if (just_dearchived_link) {
259 last_path = this_path;
260 if (! last_path_valid) {
261 last_path_valid = TRUE;
264 } while (obj_kind != ARCHIVE_END);
265 my_tt_release( mem_mark );
268 } /* pathlist_lstt_dearchive() */
271 * pathlist_lstt_archive_list() - List the LS/TT objects of the given paths.
272 * If no paths are given, list everything in the archive.
275 pathlist_lstt_archive_list(
276 _Tt_string_list_ptr paths_to_list,
280 _Tt_string last_path;
281 _Tt_string this_path;
284 bool_t last_path_valid = FALSE;
285 Object_kind obj_kind = NO_KIND;
286 Lstar_string_map_table_ptr spec_map;
287 int mem_mark = tt_mark();
289 spec_map = new Lstar_string_map_table(Lstar_string_map_old_string,
294 if (! xdr_enum( xdrs, (enum_t *)&obj_kind )) {
296 catgets(_ttcatd, 7, 8,
297 "%s: Could not read object kind "
298 "from archive stream.\n"),
299 (char *)our_process_name );
305 if (! xdr_int( xdrs, &version)) {
307 catgets(_ttcatd, 7, 9,
308 "%s: Could not read archive ver"
309 "sion from archive stream.\n"),
310 (char *)our_process_name );
313 if (version != CURRENT_ARCHIVE_VERSION) {
315 catgets(_ttcatd, 7, 10,
316 "%s: Found archive version %d, "
317 "but expected version %d.\n"),
318 (char *)our_process_name, version,
319 CURRENT_ARCHIVE_VERSION );
324 if (! spec.xdr(xdrs)) {
325 my_tt_release( mem_mark );
328 if (dearchive_this_path( (char *)spec.path(),
331 Lstar_string_map_ptr m = new Lstar_string_map;
334 * Insert it into this "map" just so that
335 * we can use the map to figure out if
336 * a given link counts under paths_to_list.
338 m->old_string_set( spec.id() );
339 m->extra_set( spec.path() );
340 spec_map->insert( m );
341 this_path = spec.path();
344 spec.print( stdout );
355 catgets(_ttcatd, 7, 11,
356 "%s: found object of unknown kind "
358 (char *)our_process_name, (int)obj_kind );
361 if ( (last_path != this_path)
362 || (obj_kind == ARCHIVE_END))
364 if (last_path_valid) {
365 if (obj_kind == SPEC) {
367 } else if (obj_kind == SUN_LINK) {
370 printf( "%s %d %s\n",
371 (char *)last_path, num_specs,
372 (num_specs == 1 ? "spec" : "specs" ));
375 if (obj_kind == SPEC) {
377 } else if (obj_kind == SUN_LINK) {
381 last_path = this_path;
382 if (! last_path_valid) {
383 last_path_valid = TRUE;
386 } while (obj_kind != ARCHIVE_END);
387 my_tt_release( mem_mark );
390 } /* pathlist_lstt_archive_list() */
393 * path_lstt_archive() - Archive the specs on the given path.
401 _Tt_string_list *specs;
402 Object_kind obj_kind;
403 int num_specs_archived = 0;
404 int num_links_archived = 0;
405 bool_t val2return = TRUE;
407 specs = new _Tt_string_list;
408 note_err( tt_file_objects_query( (char *)path, gather_specs, NULL, specs ));
409 if (IS_TT_ERR(err_noted)) {
413 while (! specs->is_empty()) {
414 _Tt_string spec = specs->top();
419 if (! xdr_enum( xdrs, (enum_t *)&obj_kind )) {
420 fprintf( stderr, "%s: ! xdr_enum()\n",
421 (char *)our_process_name );
425 if (! spec_archive( (char *)spec, (char *)path, verbosity,
431 num_specs_archived++;
433 if ((verbosity && num_specs_archived > 0 ) || (verbosity > 1)) {
435 fprintf( stderr, "\n" );
437 fprintf( stderr, "a %s: %d %s\n", (char *)path,
439 ((num_specs_archived == 1) ? "spec" : "specs" ));
444 } /* path_lstt_archive() */
448 * spec_archive() - Archive a spec onto the given XDR stream.
451 spec_archive( char *id, char *path, int verbosity, XDR *xdrs, Tt_status *err )
453 _Tt_string _path( path );
454 _Tt_string _id( id );
457 if (xdrs->x_op == XDR_ENCODE) {
458 Lstar_spec spec( _id, _path );
460 *err = spec.read_self();
461 if (IS_TT_ERR(*err)) {
464 if (! spec.xdr(xdrs)) {
468 spec.print( stderr );
475 } /* spec_archive() */
478 * spec_dearchive() - Recreate a spec that was archived on this XDR stream.
482 char **old_spec_id_ptr,
483 char **new_spec_id_ptr,
484 char **path_as_archived,
485 Lstar_string_map_list_ptr renamings,
486 char *where_to_create,
487 bool_t preserve__props,
488 bool_t (*dearchive_this_path)(char *, void *),
494 _Tt_string where( where_to_create );
497 *old_spec_id_ptr = NULL;
498 *new_spec_id_ptr = NULL;
499 *path_as_archived = NULL;
500 if (xdrs->x_op == XDR_ENCODE) {
502 } else if (xdrs->x_op == XDR_DECODE) {
506 if (! spec.xdr(xdrs)) {
509 *old_spec_id_ptr = _tt_strdup( spec.id() );
510 *path_as_archived = _tt_strdup( spec.path() );
512 if ( (dearchive_this_path == NULL)
513 || (dearchive_this_path( (char *)path, context )))
515 _Tt_string _new_name = new_name( spec.path(),
517 if (_new_name.len() > 0) {
519 fprintf( stderr, "%s => ",
520 (char *)spec.path() );
522 spec.path_set( _new_name );
524 fprintf( stderr, "%s\n",
525 (char *)spec.path() );
529 spec.write_self( where, preserve__props, err );
530 if (! IS_TT_ERR(*err) && (verbosity > 1)) {
531 spec.print( stdout );
537 } /* spec_dearchive() */
541 * dearchive_this_path() - Should we extract this <path> from its archive?
543 * Returns true if *ppaths_to_extract is an empty list.
546 dearchive_this_path( char *path, void *ppaths_to_extract )
548 _Tt_string_list_ptr paths;
549 _Tt_string _path( path );
551 if (ppaths_to_extract == NULL) {
554 paths = *(_Tt_string_list_ptr *)ppaths_to_extract;
555 if (paths->count() <= 0) {
558 return is_child_in( _path, paths );
560 } /* dearchive_this_path() */
565 static Tt_filter_action
566 gather_specs( const char *spec_id, void *, void *specs )
568 _Tt_string id = spec_id;
569 ((_Tt_string_list *)specs)->push( id );
570 return TT_FILTER_CONTINUE;