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