dtcm: Resolve CID 87408
[oweals/cde.git] / cde / programs / dtcm / libDtCmP / resource.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 /*******************************************************************************
24 **
25 **  resource.c
26 **
27 **  $XConsortium: resource.c /main/3 1995/11/03 10:38:34 rswiston $
28 **
29 **  RESTRICTED CONFIDENTIAL INFORMATION:
30 **
31 **  The information in this document is subject to special
32 **  restrictions in a confidential disclosure agreement between
33 **  HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
34 **  document outside HP, IBM, Sun, USL, SCO, or Univel without
35 **  Sun's specific written approval.  This document and all copies
36 **  and derivative works thereof must be returned or destroyed at
37 **  Sun's request.
38 **
39 **  Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
40 **
41 *******************************************************************************/
42
43 /*                                                                      *
44  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
45  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
46  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
47  * (c) Copyright 1993, 1994 Novell, Inc.                                *
48  */
49
50 #ifndef lint
51 static  char sccsid[] = "@(#)resource.c 1.9 94/11/07 Copyr 1993 Sun Microsystems, Inc.";
52 #endif
53
54 #include <EUSCompat.h>
55 #include <stdlib.h>
56 #include <stdio.h>
57 #include <string.h>
58 #include <sys/param.h>
59 #include "resource.h"
60 #include "util.h"
61
62 static const char       COMMENT         = '#';
63 static const char       CONTINUATION    = '\\';
64
65 #define MAXPROPLEN      MAXNAMELEN * 6
66
67 /*
68 **  free_resources will step the list of resources and free the allocated space
69 */
70 extern void
71 free_resources(Resource *r) {
72         if (r) {
73                 free_resources(r->next);
74                 if (r->resource_name)
75                         free(r->resource_name);
76                 if (r->resource_value)
77                         free(r->resource_value);
78                 free(r);
79         }
80 }
81
82 /*
83 **
84 **  get_resource will scan the list of resources for the resource
85 **  class.application.name (example:  deskset.calendar.start_time) passed and
86 **  return that resource's value if found, otherwise, it will return the
87 **  passed default.
88 **
89 */
90 extern char*
91 get_resource(Resource *r, char *class_name, char *app_name, char *name,
92         char *default_value)
93 {
94         char    *buf, *ret;
95
96         buf = (char *)ckalloc(cm_strlen(class_name) + cm_strlen(app_name)
97                 + cm_strlen(name) + 3);
98         sprintf(buf, "%s.%s.%s", class_name, app_name, name);
99         ret = get_resource_by_val(r, buf, default_value);
100         free(buf);
101         return ret;
102 }
103
104 /*
105 **  Same as get_resource except it just takes the entire resource name instead
106 **  of the class.application.name triplet.
107 */
108 extern char*
109 get_resource_by_val(Resource *r, char *name, char *default_value) {
110         Resource        *step = r;
111
112         while(step && strcasecmp(step->resource_name, name) != 0)
113                 step = step->next;
114         if (!step)
115                 return default_value;
116         return step->resource_value;
117 }
118
119 /*
120 **  Given a file name, read the list of resources in that file into the
121 **  passed Resource instance pointer.
122 */
123 extern boolean_t
124 load_resources(Resource **r, char *file_name) {
125         int             idx;
126         char            *c_ptr, buffer[MAXPROPLEN], value[MAXPROPLEN];
127         FILE            *rc_file;
128         boolean_t       scan_complete, end_of_file = B_FALSE;
129         Resource        *last = *r, *new_resource;
130
131         if (!(rc_file = fopen(file_name, "r")))
132                 return B_FALSE;
133
134         while(last && last->next)
135                 last = last->next;
136         while (!end_of_file && fgets(buffer, MAXPROPLEN-1, rc_file)) {
137                 if (!(c_ptr = strchr(buffer, ':')))
138                         continue;
139
140                 /*
141                 **  Add the new property to the list
142                 */
143                 *c_ptr = '\0';
144                 new_resource = (Resource *)ckalloc(sizeof(Resource));
145                 new_resource->resource_name = (char *)cm_strdup(buffer);
146                 new_resource->resource_value = NULL;
147                 new_resource->next = NULL;
148                 if (last)
149                         last->next = new_resource;
150                 else
151                         *r = new_resource;
152                 last = new_resource;
153
154                 /*
155                 **  Initialize and read the property value
156                 */
157                 idx = 0;
158                 scan_complete = B_FALSE;
159                 memset(value, '\0', MAXPROPLEN);
160                 c_ptr++;
161
162                 while (!scan_complete) {
163                         /*
164                         **  For the current buffer, skip the beginning white
165                         **  space
166                         */
167                         while (*c_ptr != '\0' && *c_ptr != '\n'
168                                 && (*c_ptr == ' ' || *c_ptr == '\t'))
169                                 c_ptr++;
170                         if (*c_ptr == '\0' || *c_ptr == '\n') {
171                                 scan_complete = B_TRUE;
172                                 continue;
173                         }
174
175                         /*
176                         **  We've found a real character, save characters until
177                         **  we find a comment, continuation, end of line, or we
178                         **  run out of space.
179                         */
180                         while (*c_ptr != '\0' && *c_ptr != '\n' &&
181                                 (idx < MAXPROPLEN - 2) && *c_ptr != COMMENT &&
182                                 *c_ptr != CONTINUATION)
183                                 value[idx++] = *c_ptr++;
184  
185                         /*
186                         **  Anything but continuation, cork value and bail
187                         */
188                         if (*c_ptr != CONTINUATION) {
189                                 value[idx] = '\0';
190                                 scan_complete = B_TRUE;
191                                 continue;
192                         }
193
194                         /*
195                         **  A continued line.  Providing we can read another
196                         **  line from the file, reset the buffer, insert a
197                         **  space, and continue the loop ...
198                         */
199                         if (!fgets(buffer, MAXPROPLEN, rc_file)) {
200                                 value[idx] = '\0';
201                                 end_of_file = scan_complete = B_TRUE;
202                                 continue;
203                         }
204
205                         value[idx++] = ' ';
206                         c_ptr = buffer;
207                 }
208                 new_resource->resource_value = (char *)cm_strdup(value);
209         }
210         fclose(rc_file);
211         return B_TRUE;
212 }
213
214 /*
215 **  This function will write the resources to disk
216 */
217 extern boolean_t
218 save_resources(Resource *r, char *file_name) {
219         char            buf[MAXPROPLEN + 3];
220         FILE            *rc_file;
221         Resource        *step = r;
222
223         if (!(rc_file = fopen(file_name, "w")))
224                 return B_FALSE;
225         while(step) {
226                 sprintf(buf, "%s:\t%s\n",
227                         step->resource_name, step->resource_value);
228                 fputs(buf, rc_file);
229                 step = step->next;
230         }
231         fclose(rc_file);
232         return B_TRUE;
233 }
234
235 /*
236 **  This set's the value for a specified resource
237 */
238 extern boolean_t
239 set_resource(Resource **r, char *class_name, char *app_name, char *name,
240         char *value)
241 {
242         boolean_t       ret;
243         char            *buf;
244
245         buf = (char *)ckalloc(cm_strlen(class_name) + cm_strlen(app_name)
246                 + cm_strlen(name) + 3);
247         sprintf(buf, "%s.%s.%s", class_name, app_name, name);
248         ret = set_resource_by_val(r, buf, value);
249         free(buf);
250         return ret;
251 }
252
253 /*
254 **  As as set_resource except the name passed in the full name
255 */
256 extern boolean_t
257 set_resource_by_val(Resource **r, char *name, char *value) {
258         Resource        *step, *last;
259
260         last = step = *r;
261         while(step && strcasecmp(step->resource_name, name) != 0)
262                 step = step->next;
263         if (step)
264                 free(step->resource_value);
265         else {
266                 step = (Resource *)ckalloc(sizeof(Resource));
267                 step->resource_name = (char *)cm_strdup(name);
268                 step->next = NULL;
269
270                 while(last && last->next)
271                         last = last->next;
272                 if (last)
273                         last->next = step;
274                 else
275                         *r = step;
276         }
277         step->resource_value = (char *)cm_strdup(value);
278
279         return B_TRUE;
280 }