/* * 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() */
/* * Lstar_spec_prop::write_self() - Write this prop onto the given spec. */ Tt_status Lstar_spec_prop:: write_self( char *spec_id, bool_t preserve__props ) { /* * If we're not root and this is a blessed property, * do not attempt to write it. * Insert link here to policy statement about prop names in tt_c.h. */ if ( (_propname[0] == '_') && ( (! preserve__props) || (getuid() != 0))) { return TT_OK; } _Tt_string_list_cursor value_cursor( this->_values ); char *val; int len; while (value_cursor.next()) { val = (char *)(*value_cursor); len = (*value_cursor).len(); note_err( tt_spec_bprop_add( spec_id, (char *)_propname, (unsigned char *)val, len)); if (IS_TT_ERR(err_noted)) { return err_noted; } } return err_noted; }
/* * Lstar_spec_prop::Lstar_spec_prop() */ Lstar_spec_prop:: Lstar_spec_prop( _Tt_string id, _Tt_string propname ) { _propname = propname; _values = new _Tt_string_list(); /* * Get how many values are in the spec's property. */ note_int_err( tt_spec_prop_count( (char *)id, (char *)propname )); switch (err_noted) { case TT_ERR_PROPNAME: case TT_ERR_OBJID: case TT_ERR_DBAVAIL: return; case TT_ERR_DBEXIST: default: if (IS_TT_ERR(err_noted)) { return; } } int num_values = int_returned; /* * Push the property's values onto our list in reverse order, * to preserve the order they had. */ for (int n = num_values - 1; n >= 0; n--) { int len; unsigned char *value; note_err( tt_spec_bprop( (char *)id, (char *)propname, n, &value, &len )); switch (err_noted) { case TT_ERR_PROPNAME: case TT_ERR_OBJID: case TT_ERR_DBAVAIL: return; case TT_ERR_NUM: continue; case TT_ERR_DBEXIST: default: if (IS_TT_ERR(err_noted)) { return; } } _Tt_string val( value, len ); this->_values->push( val ); } }
/* * 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() */
/* * Lstar_spec::read_self() - Read from ToolTalk everything we need to know * about ourselves in order to archive ourself. */ Tt_status Lstar_spec:: read_self() { /* * Get the spec's type. */ note_ptr_err( tt_spec_type( (char *)_id )); if (IS_TT_ERR(err_noted)) { return err_noted; } _type = ptr_returned; /* * Get how many properties are on the spec. */ note_int_err( tt_spec_propnames_count( (char *)_id )); if (IS_TT_ERR(err_noted)) { return err_noted; } int num_props = int_returned; /* * Push the spec's properties onto our list in reverse order, * to preserve the admittedly meaningless order they had. */ for (int n = num_props - 1; n >= 0; n--) { note_ptr_err( tt_spec_propname( (char *)_id, n )); switch (err_noted) { case TT_ERR_OBJID: case TT_ERR_DBAVAIL: return err_noted; case TT_ERR_NUM: continue; case TT_ERR_DBEXIST: default: if (IS_TT_ERR(err_noted)) { return err_noted; } } _Tt_string propname = ptr_returned; Lstar_spec_prop_ptr prop_ptr; prop_ptr = new Lstar_spec_prop( _id, propname ); this->_props->push( prop_ptr ); } return err_noted; }
/* * Lstar_spec::write_self() - Recreate a spec like the one we are, returning * the id of the spec created. The string returned must be freed * using tt_free(). */ char * Lstar_spec:: write_self( _Tt_string where, bool_t preserve__props, Tt_status *err ) { char *spec_created = NULL; _Tt_string path; if (this->_path.len() <= 0) { *err = TT_ERR_PATH; return NULL; } /* * TO_DO: tt_spec_create() won't convert /./ to / in a path * if the path doesn't exist. */ if (this->_path.left(2) == "./") { this->_path = this->_path.right( _path.len() - 2 ); } /* * If the archived path is absolute, ignore <where>. */ if (this->_path[0] == '/') { path = this->_path; } else { path = where.cat( "/" ).cat( this->_path ); } note_ptr_err( tt_spec_create( (char *)path )); *err = err_noted; spec_created = ptr_returned; if (IS_TT_ERR(err_noted)) { return spec_created; } note_err( tt_spec_type_set( spec_created, (char *)this->_type )); *err = err_noted; if (IS_TT_ERR(err_noted)) { return spec_created; } Lstar_spec_prop_list_cursor prop_cursor( this->_props ); while (prop_cursor.next()) { *err = prop_cursor->write_self( spec_created, preserve__props ); } note_err( tt_spec_write( spec_created )); *err = err_noted; return spec_created; }
/* * 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() */