FreeBSD 10 clang port
[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
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
187 /* ___________________________________________________________________
188 **|                                                                   |
189 **| PathInPList(path,fplist,listlen) -                                |
190 **|                                                                   |
191 **|     Determine if a specific fontpath element is in a list,        |
192 **|     taking into account that identical elements may be formed     |
193 **|     differently (with multiple embedded and trailing slashes).    |
194 **|                                                                   |
195 **| Specify: (char *)path = the single element to be tested           |
196 **|          (char **)fplist = list of ptrs to asciz elements         |
197 **|          (int)listlen = number of pointers in the list            |
198 **|                                                                   |
199 **| Returns: TRUE if element is in the list                           |
200 **|___________________________________________________________________|
201 */
202
203 static int
204 PathInPList(char *path, char **fplist, int listlen)
205 {
206     char *s,*t;
207     while (listlen-- > 0) {
208         for (s=path, t=fplist[listlen]; *s && (*s == *t); ) {
209             t++; while (*t == '/') t++;
210             s++; while (*s == '/') s++;
211         }
212         if (!*s && !*t) return 1;
213     }
214     return 0;    
215 }
216
217 /* ___________________________________________________________________
218 **|                                                                   |
219 **| PathInZList(path,fplist,listlen) -                                |
220 **|                                                                   |
221 **|     Determine if a specific fontpath element is in a list,        |
222 **|     taking into account that identical elements may be formed     |
223 **|     differently (with multiple embedded and trailing slashes).    |
224 **|                                                                   |
225 **| Specify: (char *)path = the single element to be tested           |
226 **|          (char *)fplist = list of concatenated asciz elements     |
227 **|          (int)listlen = number of elements in the list            |
228 **|                                                                   |
229 **| Returns: TRUE if element is in the list                           |
230 **|___________________________________________________________________|
231 */
232
233 static int
234 PathInZList(char *path, char *fplist, int listlen)
235 {
236     char *s,*t;
237     for (t=fplist; listlen > 0; listlen--) {
238         for (s=path; *s && (*s == *t); ) {
239             t++; while (*t == '/') t++;
240             s++; while (*s == '/') s++;
241         }
242         if (!*s && !*t) return 1;
243         while (*t) t++; t++;
244     }
245     return 0;    
246 }
247
248 /* ________________________________________________________________
249 **|                                                                |
250 **| SeparateParts(path)                                            |
251 **|                                                                |
252 **|     Break a comma-delimited asciz path string into its         |
253 **|     separate asciz constituent parts.                          |
254 **|                                                                |
255 **| Specify: path = ptr to asciz path string (e.g., "as,df,jk")    |
256 **|                                                                |
257 **| Returns: number of constituent parts, with path string         |
258 **|          converted into as many sequential asciz strings       |
259 **|          (e.g., "as\0df\0jk").                                 |
260 **|________________________________________________________________|
261 */
262
263 static int
264 SeparateParts( char **path )
265 {
266     char *t,*s;
267     int nparts = 0;
268     if (path && *path)
269         for (s=*path; t=strtok(s,","); s=NULL, nparts++);
270     return nparts;
271 }
272
273 /* ___________________________________________________________________
274 **|                                                                   |
275 **| GetSysParms(tzpp,fhpp,ftpp) -                                     |
276 **|                                                                   |
277 **|     Extract TZ, FONT_PATH_HEAD, and FONT_PATH_TAIL definitions    |
278 **|     from the sys parms file (typically /etc/src.sh).              |
279 **|                                                                   |
280 **| Specify: (char **)tzpp = where to put ptr to TZ string            |
281 **|          (char **)fhpp = where to put ptr to FONT_PATH_HEAD       |
282 **|          (char **)ftpp = where to put ptr to FONT_PATH_TAIL       |
283 **|                                                                   |
284 **|     Specify a NULL (char **) for any undesired strings.           |
285 **|                                                                   |
286 **| Returns: Appropriate pointers to malloc'ed strings (NULL pointer  |
287 **|          if a string is neither requested nor defined).           |
288 **|___________________________________________________________________|
289 */
290
291 void
292 GetSysParms( char **tzpp, char **fhpp, char **ftpp )
293 {
294     FILE *fin;
295     char *s,*t,buf[256];
296
297     if (tzpp) *tzpp = NULL;
298     if (fhpp) *fhpp = NULL;
299     if (ftpp) *ftpp = NULL;
300     if ((*sysParmsFile != '/') || !(fin=fopen(sysParmsFile,"r"))) {
301         Debug("(GetSysParms) Can't open sys parms file\n");
302         return;
303     }
304     Debug("(GetSysParms) Reading sys parms file\n");
305     while (fgets(buf,255,fin)) {
306         for (t=buf; *t && *t<=' '; t++); /* t -> EOS or nonblank */
307         if (!*t || *t=='#') continue;    /* ignore comment lines */
308         while (*t && *t!='\n') t++;      /* t -> EOS or newline  */
309         if (*t) *t = '\0';               /* discard newline char */
310         if (tzpp && !*tzpp)
311             if ((s=strstr(buf,"TZ=")) && (t=strtok(s+3,"; \t")))
312                 *tzpp = (char *) strdup(t);
313         if (fhpp && !*fhpp)
314             if ((s=strstr(buf,"FONT_PATH_HEAD=")) && (t=strtok(s+15,"; \t")))
315                 *fhpp = (char *) strdup(t);
316         if (ftpp && !*ftpp)
317             if ((s=strstr(buf,"FONT_PATH_TAIL=")) && (t=strtok(s+15,"; \t")))
318                 *ftpp = (char *) strdup(t);
319     }
320     fclose(fin);
321 }    
322