remove ultrix support
[oweals/cde.git] / cde / lib / tt / bin / dbck / spec_repair.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 libraries 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: spec_repair.C /main/3 1995/10/20 16:26:51 rswiston $                                                        
28 /*
29  *
30  * spec_repair.cc
31  *
32  * Copyright (c) 1990 by Sun Microsystems, Inc.
33  */
34
35 #include <stddef.h>
36 #include <stdio.h>
37 #include <errno.h>
38 #if defined(_AIX)
39 #include <time.h>
40 #endif
41 #include <sys/stat.h>
42 #include "spec.h"
43 #include "options_tt.h"
44 #include "ttdbck.h"
45 #include "db/tt_db_object.h"
46 #include "db/tt_db_object_utils.h"
47 #include "db/tt_db_key.h"
48 #include "db/tt_db_object.h"
49 #include "db/tt_db_results.h"
50 #include "db/tt_db_access.h"
51 #include "tt_db_server_consts.h"     
52      
53 #define MKERR(msg, err) fprintf(stderr, \
54                                 "ttdbck: error %s spec: %s\n", \
55                                 msg, \
56                                 tt_status_message(err))
57
58 const char* MP_TYPE_PROP = "_NODE_TYPE";
59
60      void Spec::
61      repair_spec()
62 {
63         
64         // by this point all the information about the spec is collected
65         // in the Spec instance.  We make any requested changes to
66         // the Spec instance, then completely replace the
67         // info on disk with the info from the Spec instance.
68         
69         if (opts->repair_type_p()) {
70                 type = opts->repair_type();
71         }
72         
73         if (opts->repair_filename_p()) {
74                 filename = opts->repair_filename();
75         }
76
77         _Tt_db_object_ptr oldobj = new _Tt_db_object();
78         switch(oldobj->getDBResults()) {
79             case TT_DB_OK:
80                 break;
81             default:
82                 MKERR("creating", TT_ERR_INTERNAL);
83                 return;
84         }
85
86         _Tt_string objid = oldobj->create(filename, key->key()->string());
87         switch(oldobj->getDBResults()) {
88             case TT_DB_OK:
89                 break;
90             default:
91                 MKERR("creating", TT_ERR_INTERNAL);
92                 return;
93         }
94
95         _Tt_db_access_ptr access = oldobj->getAccess();
96         switch(oldobj->getDBResults()) {
97             case TT_DB_OK:
98                 break;
99             default:
100                 MKERR("creating", TT_ERR_INTERNAL);
101                 return;
102         }
103         
104         switch(oldobj->remove()) {
105             case TT_DB_OK:
106             case TT_DB_ERR_NO_SUCH_OBJECT:
107             case TT_DB_ERR_NO_SUCH_PROPERTY:
108             case TT_DB_WRN_FORWARD_POINTER:
109                 break;
110             case TT_DB_ERR_ACCESS_DENIED:
111                 MKERR("destroying", TT_ERR_ACCESS);
112                 return;
113             default:
114                 MKERR("destroying", TT_ERR_DBAVAIL);
115                 return;
116         }
117
118         if (opts->repair_delete_p()) {
119                 // don't recreate the spec.
120         } else {
121
122                 // Should ensure we are running under a particular namespace
123                 // for this?  Like an override namespace to force into the
124                 // db under repair?
125                 
126                 _Tt_db_object_ptr newobj = new _Tt_db_object();
127                 switch(newobj->getDBResults()) {
128                     case TT_DB_OK:
129                         break;
130                     default:
131                         MKERR("creating", TT_ERR_INTERNAL);
132                         return;
133                 }
134
135                 _Tt_string newobjid = newobj->create(filename,
136                                                      key->key()->string());
137                 switch(newobj->getDBResults()) {
138                     case TT_DB_OK:
139                         break;
140                     default:
141                         MKERR("creating", TT_ERR_INTERNAL);
142                         return;
143                 }
144
145                 newobj->setType(type);
146                 newobj->setAccess(access);
147
148                 // Re-create the properties
149                 
150                 _Tt_string_list_cursor c;
151                 Prop_ptr sp;
152                 _Tt_string_list_cursor v;
153                 _Tt_db_property_ptr dbprop = new _Tt_db_property();
154                 uid_t euid;
155                 gid_t group;
156                 mode_t mode;
157                 int owner_written = 0;
158                 int group_written = 0;
159                 int mode_written = 0;
160
161                 c.reset(propnames);
162                 while(c.next()) {
163                         sp = props->lookup(*c);
164                         v.reset(sp->_values);
165                         if (!v.next()) {
166                                 // No values for the property.  This is
167                                 // theoretically impossible -- delete the
168                                 // property.
169                         } else if (sp->_name == TT_DB_OBJECT_TYPE_PROPERTY) {
170                                 // this is the special prop that holds the
171                                 // type name. Don't try to set it by that name.
172                         } else {
173
174                                 if (sp->_name ==
175                                     TT_OBJECT_OWNER_PROPERTY) {
176                                 
177                                         // This is the special user field
178                                         // Note that the access info is
179                                         // already written out above.
180                                         // Re-write it here anyway, in
181                                         // case it was corrupt in the
182                                         // old DB.
183
184                                         memcpy((char *)&euid,
185                                                (char *)(*v), sizeof(uid_t));
186                                         owner_written = 1;
187                                 }
188                                 else if (sp->_name ==
189                                          TT_OBJECT_GROUP_PROPERTY) {
190                                 
191                                         // This is the special group field
192                                         // See note for owner field above
193
194                                         memcpy((char *)&group,
195                                                (char *)(*v), sizeof(gid_t));
196                                         group_written = 1;
197                                 }
198                                 else if (sp->_name ==
199                                          TT_OBJECT_MODE_PROPERTY) {
200                                 
201                                         // This is the special mode field
202                                         // See note for owner field above
203
204                                         memcpy((char *)&mode,
205                                                (char *)(*v), sizeof(mode_t));
206                                         mode_written = 1;
207                                 }
208                                 else {
209
210                                         // Ordinary property -- create
211                                         // a new _Tt_db_property record
212
213                                         dbprop->name = sp->_name;
214                                         dbprop->values->push(*v);
215
216                                         while(v.next()) {
217
218                                                 // Add any remaining values
219
220                                                 dbprop->values->push(*v);
221                                         }
222
223                                 }
224                         }
225
226                         newobj->addProperty(dbprop);
227                 }
228
229                 if (owner_written && group_written && mode_written) {
230
231                         // We have complete access info from the old prop
232                         // list, so we may as well use it.
233
234                         access->user = euid;
235                         access->group = group;
236                         access->mode = mode;
237                         newobj->setAccess(access);
238                 }
239
240                 // There\'s not much we can do if this call doesn\'t work
241                 
242                 newobj->write();
243         }
244 }