Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / tt / bin / tttar / tttar_spec.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
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
22  */
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_spec.C /main/3 1995/10/20 17:00:42 rswiston $                                                         
28 /*
29  * tttar_spec.cc - Implementation of specs for Link Service/ToolTalk archiving
30  *
31  * Copyright (c) 1990 by Sun Microsystems, Inc.
32  *
33  */
34
35 #if defined(__osf__)
36 #include <unistd.h>
37 #else
38 #if defined (USL) || defined(__uxp__)
39 #include "tt_options.h"
40 #if defined(OPT_BUG_USL) || defined(OPT_BUG_UXP)
41 #include <unistd.h>
42 #else
43 #include <osfcn.h>
44 #endif /* if defined(OPT_BUG_USL) || defined(OPT_BUG_UXP) */
45 #else
46 #include <osfcn.h>
47 #endif
48 #endif /* __osf__ */
49 #include "api/c/tt_c.h"
50 #include "util/tt_iostream.h"
51 #include "tttar_utils.h"
52 #include "tttar_spec.h"
53
54 /*
55  * Lstar_spec::Lstar_spec()
56  */
57 Lstar_spec::
58 Lstar_spec()
59 {
60         _props = new Lstar_spec_prop_list();
61 }
62
63 /*
64  * Lstar_spec::Lstar_spec() - 
65  */
66 Lstar_spec::
67 Lstar_spec(  _Tt_string id, _Tt_string path )
68 {
69         _id = id;
70         _path = path;
71         _props = new Lstar_spec_prop_list();
72 }
73
74 /*
75  * Lstar_spec::~Lstar_spec()
76  */
77 Lstar_spec::
78 ~Lstar_spec()
79 {
80 }
81
82 /*
83  * Lstar_spec::xdr()
84  */
85 bool_t Lstar_spec::
86 xdr( XDR *xdrs )
87 {
88         if (! this->_id.xdr(xdrs)) {
89                 return FALSE;
90         }
91         if (! this->_path.xdr(xdrs)) {
92                 return FALSE;
93         }
94         if (! this->_type.xdr(xdrs)) {
95                 return FALSE;
96         }
97         if (! this->_props.xdr(xdrs)) {
98                 return FALSE;
99         }
100         return TRUE;
101 }
102
103 /*
104  * Lstar_spec::read_self() - Read from ToolTalk everything we need to know
105  *      about ourselves in order to archive ourself.
106  */
107 Tt_status Lstar_spec::
108 read_self()
109 {
110         /*
111          * Get the spec's type.
112          */
113         note_ptr_err( tt_spec_type( (char *)_id ));
114         if (IS_TT_ERR(err_noted)) {
115                 return err_noted;
116         }
117         _type = ptr_returned;
118         /*
119          * Get how many properties are on the spec.
120          */
121         note_int_err( tt_spec_propnames_count( (char *)_id ));
122         if (IS_TT_ERR(err_noted)) {
123                 return err_noted;
124         }
125         int num_props = int_returned;
126         /*
127          * Push the spec's properties onto our list in reverse order,
128          * to preserve the admittedly meaningless order they had.
129          */
130         for (int n = num_props - 1; n >= 0; n--) {
131                 note_ptr_err( tt_spec_propname( (char *)_id, n ));
132                 switch (err_noted) {
133                     case TT_ERR_OBJID:
134                     case TT_ERR_DBAVAIL:
135                         return err_noted;
136                     case TT_ERR_NUM:
137                         continue;
138                     case TT_ERR_DBEXIST:
139                     default:
140                         if (IS_TT_ERR(err_noted)) {
141                                 return err_noted;
142                         }
143                 }
144                 _Tt_string              propname = ptr_returned;
145                 Lstar_spec_prop_ptr     prop_ptr;
146
147                 prop_ptr = new Lstar_spec_prop( _id, propname );
148                 this->_props->push( prop_ptr );
149         }
150         return err_noted;
151 }
152
153 /*
154  * Lstar_spec::write_self() - Recreate a spec like the one we are, returning
155  *      the id of the spec created.  The string returned must be freed
156  *      using tt_free().
157  */
158 char * Lstar_spec::
159 write_self( _Tt_string where, bool_t preserve__props, Tt_status *err )
160 {
161         char           *spec_created = NULL;
162         _Tt_string      path;
163
164         if (this->_path.len() <= 0) {
165                 *err = TT_ERR_PATH;
166                 return NULL;
167         }
168         /*
169          * TO_DO: tt_spec_create() won't convert /./ to / in a path
170          * if the path doesn't exist.
171          */
172         if (this->_path.left(2) == "./") {
173                 this->_path = this->_path.right( _path.len() - 2 );
174         }
175         /*
176          * If the archived path is absolute, ignore <where>.
177          */
178         if (this->_path[0] == '/') {
179                 path = this->_path;
180         } else {
181                 path = where.cat( "/" ).cat( this->_path );
182         }
183         note_ptr_err( tt_spec_create( (char *)path ));
184         *err = err_noted;
185         spec_created = ptr_returned;
186         if (IS_TT_ERR(err_noted)) {
187                 return spec_created;
188         }
189         note_err( tt_spec_type_set( spec_created, (char *)this->_type ));
190         *err = err_noted;
191         if (IS_TT_ERR(err_noted)) {
192                 return spec_created;
193         }
194         Lstar_spec_prop_list_cursor prop_cursor( this->_props );
195         while (prop_cursor.next()) {
196                 *err = prop_cursor->write_self( spec_created, preserve__props );
197         }
198         note_err( tt_spec_write( spec_created ));
199         *err = err_noted;
200         return spec_created;
201 }
202
203 /*
204  * Lstar_spec::print()
205  */
206 void Lstar_spec::
207 print( FILE *fs ) const
208 {
209         fprintf( fs, "spec id: "  );
210         this->_id.print( fs );
211         fprintf( fs, "\nspec type: " );
212         this->_type.print( fs );
213         fprintf( fs, "\nspec path: " );
214         this->_path.print( fs );
215         fprintf( fs, "\n" );
216         this->_props->print(Lstar_spec::do_print, fs );
217         fprintf( fs, "\n" );
218 }
219
220 implement_list_of(Lstar_spec_prop)
221
222 /*
223  * Lstar_spec_prop::Lstar_spec_prop()
224  */
225 Lstar_spec_prop::
226 Lstar_spec_prop()
227 {
228 }
229
230 /*
231  * Lstar_spec_prop::Lstar_spec_prop()
232  */
233 Lstar_spec_prop::
234 Lstar_spec_prop( _Tt_string id, _Tt_string propname )
235 {
236         _propname = propname;
237         _values = new _Tt_string_list();
238         /*
239          * Get how many values are in the spec's property.
240          */
241         note_int_err( tt_spec_prop_count( (char *)id, (char *)propname ));
242         switch (err_noted) {
243             case TT_ERR_PROPNAME:
244             case TT_ERR_OBJID:
245             case TT_ERR_DBAVAIL:
246                 return;
247             case TT_ERR_DBEXIST:
248             default:
249                 if (IS_TT_ERR(err_noted)) {
250                         return;
251                 }
252         }
253         int num_values = int_returned;
254         /*
255          * Push the property's values onto our list in reverse order,
256          * to preserve the order they had.
257          */
258         for (int n = num_values - 1; n >= 0; n--) {
259                 int             len;
260                 unsigned char  *value;
261
262                 note_err( tt_spec_bprop( (char *)id, (char *)propname, n, &value, &len ));
263                 switch (err_noted) {
264                     case TT_ERR_PROPNAME:
265                     case TT_ERR_OBJID:
266                     case TT_ERR_DBAVAIL:
267                         return;
268                     case TT_ERR_NUM:
269                         continue;
270                     case TT_ERR_DBEXIST:
271                     default:
272                         if (IS_TT_ERR(err_noted)) {
273                                 return;
274                         }
275                 }
276                 _Tt_string val( value, len );
277                 this->_values->push( val );
278         }
279 }
280
281 /*
282  * Lstar_spec_prop::~Lstar_spec_prop()
283  */
284 Lstar_spec_prop::
285 ~Lstar_spec_prop()
286 {
287 }
288
289 /*
290  * Lstar_spec_prop::xdr()
291  */
292 bool_t Lstar_spec_prop::
293 xdr( XDR *xdrs )
294 {
295         if (! this->_propname.xdr(xdrs)) {
296                 return FALSE;
297         }
298         if (! this->_values.xdr(xdrs)) {
299                 return FALSE;
300         }
301         return TRUE;
302 }
303
304 /*
305  * Lstar_spec_prop::write_self() - Write this prop onto the given spec.
306  */
307 Tt_status Lstar_spec_prop::
308 write_self( char *spec_id, bool_t preserve__props )
309 {
310         /*
311          * If we're not root and this is a blessed property,
312          * do not attempt to write it.
313          * Insert link here to policy statement about prop names in tt_c.h.
314          */
315         if (    (_propname[0] == '_')
316              && (    (! preserve__props)
317                   || (getuid() != 0)))
318         {
319                 return TT_OK;
320         }
321         _Tt_string_list_cursor value_cursor( this->_values );
322         char    *val;
323         int     len;
324         while (value_cursor.next()) {
325                 val = (char *)(*value_cursor);
326                 len = (*value_cursor).len();
327                 note_err( tt_spec_bprop_add( spec_id, (char *)_propname,
328                                             (unsigned char *)val, len));
329                 if (IS_TT_ERR(err_noted)) {
330                         return err_noted;
331                 }
332         }
333         return err_noted;
334 }
335
336 /*
337  * Lstar_spec_prop::print()
338  */
339 void Lstar_spec_prop::
340 print( FILE *fs ) const
341 {
342         this->_propname.print( fs );
343         fprintf( fs, ": " );
344         this->_values->print(_tt_string_print,fs);
345         fprintf( fs, "\n" );
346 }
347
348 void Lstar_spec::
349 do_print(const _Tt_ostream &os, const _Tt_object *obj)
350 {
351         ((Lstar_spec *)obj)->print(os.theFILE());
352 }
353
354 void Lstar_spec_prop::
355 do_print(FILE *fs, const _Tt_object *obj)
356 {
357         ((Lstar_spec_prop *)obj)->print(fs);
358 }
359