dtlogin: start to resolve static analysis warnings
[oweals/cde.git] / cde / programs / dtlogin / fontpath.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 /* $XConsortium: fontpath.c /main/4 1995/10/27 16:13:29 rswiston $ */
24 /*                                                                      *
25  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
26  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
27  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
28  * (c) Copyright 1993, 1994 Novell, Inc.                                *
29  */
30 /*
31 **  fontpath.c - font path modification routines
32 **
33 **  $fontpath.c,v 1.1 93/06/24 14:52:10 bill Exp $
34 **
35 **  Copyright 1993 Hewlett-Packard Company
36 */
37
38 # include "dm.h"
39 # include <signal.h>
40 # include <X11/Xatom.h>
41 # include <setjmp.h>
42 #if defined(__FreeBSD__) && OSMAJORVERSION > 8
43 # include <utmpx.h>
44 #else
45 # include <utmp.h>
46 #endif
47 # include "vgproto.h"
48
49 /* 
50 **  Prototypes
51 */
52
53
54 int ApplyFontPathMods( struct display *d, Display *dpy );
55 void GetSysParms( char **tzpp, char **fhpp, char **ftpp );
56 static int PathInPList(char *path, char **fplist, int listlen);
57 static int PathInZList(char *path, char *fplist, int listlen);
58 static int SeparateParts( char **path );
59
60
61 static void
62 DebugFontPath(char *note, char **path, int nelems)
63 {
64     int i;
65     Debug("  %s: %d elements\n",note,nelems);
66     for (i=0; i<nelems; i++)
67         Debug("    %s\n",path[i]);
68 }
69
70 static int 
71 ErrorHandler(Display *dpy, XErrorEvent *event)
72 {
73     XmuPrintDefaultErrorMessage(dpy, event, stderr);
74     return 0; /* nonfatal */
75 }
76
77 /* ________________________________________________________________
78 **|                                                                |
79 **| ApplyFontPathMods(d) -                                         |
80 **|                                                                |
81 **|     If new font path mods are mandated, fabricate and apply    |
82 **|     an appropriate new complete X server font path.            |
83 **|                                                                |
84 **| Specify: d = pointer to display structure                      |
85 **|                                                                |
86 **| Returns: nothing                                               |
87 **|________________________________________________________________|
88 */
89
90 int 
91 ApplyFontPathMods( struct display *d, Display *dpy )
92 {
93     FILE *fin;
94     char *s,*t;
95     char *fph = NULL;
96     char *fpt = NULL;
97     char **fontPath,**newList;
98     int numHeads = 0;
99     int numTails = 0;
100     int i,j,k,numPaths;
101
102     Debug("ApplyFontPathMods() for %s\n",d->name);
103
104     if (d->displayType.location == Foreign) {
105         Debug("  Foreign display\n");
106         return 0;
107     }
108
109     if (!(fontPath=XGetFontPath(dpy, &numPaths))) {
110         Debug("  Can't get font path\n");
111         return 0;
112     }
113
114     /*
115     **  Font path mods can come from (in priority order):
116     **
117     **    1. FONT_PATH_HEAD/TAIL definitions in /etc/src.sh
118     **    2. fontPathHead/Tail resources
119     */
120
121     GetSysParms(0,&fph,&fpt);
122
123     if (fph)          { s = "sys parm file"; }
124     else if (fpHead)  { s = "resource"; fph = strdup(fpHead); }
125     if (fph && !*fph) { free(fph); fph = NULL; }
126     if (fph)          Debug("  +fp (%s) %s\n",s,fph);
127
128     if (fpt)          { s = "sys parm file"; }
129     else if (fpTail)  { s = "resource"; fpt = strdup(fpTail); }
130     if (fpt && !*fpt) { free(fpt); fpt = NULL; }
131     if (fpt)          Debug("  fp+ (%s) %s\n",s,fpt);
132
133     /* 
134     **  Break up fph and fpt into constituent parts and 
135     **  then reconstruct the complete, modified font path.
136     **  During reconstruction we also eliminate redundancies.
137     */
138
139     numHeads = SeparateParts(&fph);
140     numTails = SeparateParts(&fpt);
141     if (numHeads || numTails) {
142         newList = (char **) malloc((numHeads+numPaths+numTails)
143             * sizeof(char *));
144         if (newList) {
145             for (s=fph, i=j=0; j<numHeads; j++) {
146                 if (!PathInPList(s,newList,i))
147                     newList[i++] = s;
148                 while (*s) s++; s++;
149             }
150             for (j=0; j<numPaths; j++) {
151                 if (!PathInPList(fontPath[j],newList,i) &&
152                     !PathInZList(fontPath[j],fpt,numTails)) {
153                     newList[i++] = fontPath[j];
154                 }
155             }
156             for (s=fpt, j=0; j<numTails; j++) {
157                 if (!PathInPList(s,newList,i))
158                     newList[i++] = s;   
159                 while (*s) s++; s++;
160             }
161             if (debugLevel > 0)
162                 DebugFontPath("Request (XSetFontPath)",newList,i);
163
164             /*
165             **  Tell X server to set new font path now.  Log failure,
166             **  but don't let it be fatal.  (Note that caller should
167             **  reset error handler to elsewhere when we return.)
168             */
169
170             (void)XSetErrorHandler(ErrorHandler);
171             XSetFontPath(dpy, newList, i);
172             XSync(dpy, True);
173             free(newList);
174             if (debugLevel > 0) {
175                 newList = XGetFontPath(dpy, &i);
176                 DebugFontPath("Confirm (XGetFontPath)",newList,i);
177                 XFreeFontPath(newList);
178             }
179         }
180     }
181
182     if (fph) free(fph);
183     if (fpt) free(fpt);
184     XFreeFontPath(fontPath);
185
186     return 1;
187 }
188
189 /* ___________________________________________________________________
190 **|                                                                   |
191 **| PathInPList(path,fplist,listlen) -                                |
192 **|                                                                   |
193 **|     Determine if a specific fontpath element is in a list,        |
194 **|     taking into account that identical elements may be formed     |
195 **|     differently (with multiple embedded and trailing slashes).    |
196 **|                                                                   |
197 **| Specify: (char *)path = the single element to be tested           |
198 **|          (char **)fplist = list of ptrs to asciz elements         |
199 **|          (int)listlen = number of pointers in the list            |
200 **|                                                                   |
201 **| Returns: TRUE if element is in the list                           |
202 **|___________________________________________________________________|
203 */
204
205 static int
206 PathInPList(char *path, char **fplist, int listlen)
207 {
208     char *s,*t;
209     while (listlen-- > 0) {
210         for (s=path, t=fplist[listlen]; *s && (*s == *t); ) {
211             t++; while (*t == '/') t++;
212             s++; while (*s == '/') s++;
213         }
214         if (!*s && !*t) return 1;
215     }
216     return 0;    
217 }
218
219 /* ___________________________________________________________________
220 **|                                                                   |
221 **| PathInZList(path,fplist,listlen) -                                |
222 **|                                                                   |
223 **|     Determine if a specific fontpath element is in a list,        |
224 **|     taking into account that identical elements may be formed     |
225 **|     differently (with multiple embedded and trailing slashes).    |
226 **|                                                                   |
227 **| Specify: (char *)path = the single element to be tested           |
228 **|          (char *)fplist = list of concatenated asciz elements     |
229 **|          (int)listlen = number of elements in the list            |
230 **|                                                                   |
231 **| Returns: TRUE if element is in the list                           |
232 **|___________________________________________________________________|
233 */
234
235 static int
236 PathInZList(char *path, char *fplist, int listlen)
237 {
238     char *s,*t;
239     for (t=fplist; listlen > 0; listlen--) {
240         for (s=path; *s && (*s == *t); ) {
241             t++; while (*t == '/') t++;
242             s++; while (*s == '/') s++;
243         }
244         if (!*s && !*t) return 1;
245         while (*t) t++; t++;
246     }
247     return 0;    
248 }
249
250 /* ________________________________________________________________
251 **|                                                                |
252 **| SeparateParts(path)                                            |
253 **|                                                                |
254 **|     Break a comma-delimited asciz path string into its         |
255 **|     separate asciz constituent parts.                          |
256 **|                                                                |
257 **| Specify: path = ptr to asciz path string (e.g., "as,df,jk")    |
258 **|                                                                |
259 **| Returns: number of constituent parts, with path string         |
260 **|          converted into as many sequential asciz strings       |
261 **|          (e.g., "as\0df\0jk").                                 |
262 **|________________________________________________________________|
263 */
264
265 static int
266 SeparateParts( char **path )
267 {
268     char *t,*s;
269     int nparts = 0;
270     if (path && *path)
271         for (s=*path; t=strtok(s,","); s=NULL, nparts++);
272     return nparts;
273 }
274
275 /* ___________________________________________________________________
276 **|                                                                   |
277 **| GetSysParms(tzpp,fhpp,ftpp) -                                     |
278 **|                                                                   |
279 **|     Extract TZ, FONT_PATH_HEAD, and FONT_PATH_TAIL definitions    |
280 **|     from the sys parms file (typically /etc/src.sh).              |
281 **|                                                                   |
282 **| Specify: (char **)tzpp = where to put ptr to TZ string            |
283 **|          (char **)fhpp = where to put ptr to FONT_PATH_HEAD       |
284 **|          (char **)ftpp = where to put ptr to FONT_PATH_TAIL       |
285 **|                                                                   |
286 **|     Specify a NULL (char **) for any undesired strings.           |
287 **|                                                                   |
288 **| Returns: Appropriate pointers to malloc'ed strings (NULL pointer  |
289 **|          if a string is neither requested nor defined).           |
290 **|___________________________________________________________________|
291 */
292
293 void
294 GetSysParms( char **tzpp, char **fhpp, char **ftpp )
295 {
296     FILE *fin;
297     char *s,*t,buf[256];
298
299     if (tzpp) *tzpp = NULL;
300     if (fhpp) *fhpp = NULL;
301     if (ftpp) *ftpp = NULL;
302     if ((*sysParmsFile != '/') || !(fin=fopen(sysParmsFile,"r"))) {
303         Debug("(GetSysParms) Can't open sys parms file\n");
304         return;
305     }
306     Debug("(GetSysParms) Reading sys parms file\n");
307     while (fgets(buf,255,fin)) {
308         for (t=buf; *t && *t<=' '; t++); /* t -> EOS or nonblank */
309         if (!*t || *t=='#') continue;    /* ignore comment lines */
310         while (*t && *t!='\n') t++;      /* t -> EOS or newline  */
311         if (*t) *t = '\0';               /* discard newline char */
312         if (tzpp && !*tzpp)
313             if ((s=strstr(buf,"TZ=")) && (t=strtok(s+3,"; \t")))
314                 *tzpp = (char *) strdup(t);
315         if (fhpp && !*fhpp)
316             if ((s=strstr(buf,"FONT_PATH_HEAD=")) && (t=strtok(s+15,"; \t")))
317                 *fhpp = (char *) strdup(t);
318         if (ftpp && !*ftpp)
319             if ((s=strstr(buf,"FONT_PATH_TAIL=")) && (t=strtok(s+15,"; \t")))
320                 *ftpp = (char *) strdup(t);
321     }
322     fclose(fin);
323 }    
324