|
|
1.1 root 1: /***********************************************************
2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
4:
5: All Rights Reserved
6:
7: Permission to use, copy, modify, and distribute this software and its
8: documentation for any purpose and without fee is hereby granted,
9: provided that the above copyright notice appear in all copies and that
10: both that copyright notice and this permission notice appear in
11: supporting documentation, and that the names of Digital or MIT not be
12: used in advertising or publicity pertaining to distribution of the
13: software without specific, written prior permission.
14:
15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21: SOFTWARE.
22:
23: ******************************************************************/
24: /* $Header: filenames.c,v 1.27 87/09/08 08:50:26 swick Exp $ */
25:
26: #include <stdio.h>
27: #include <sys/types.h>
28: #include <ndir.h>
29: #include <ctype.h>
30: #include <strings.h>
31: #include "misc.h"
32: #include "resource.h"
33: #include "osstruct.h"
34: #include "X.h"
35: #include "Xmd.h"
36: #include "opaque.h"
37:
38: extern char *defaultFontPath;
39:
40: /* The fontSearchList should contain zero paths to start with. */
41: static FontPathRec fontSearchList = { 0, 0, 0};
42:
43: /*
44: * description
45: * DDX interface routines
46: *
47: * caveats:
48: * These are OS-dependent to the extent that they assume pathnames contain
49: * no NULL characters.
50: */
51:
52:
53: /*
54: * This is called from main.c, not in response to a protocol request, so it
55: * may take a null-terminated string as argument.
56: */
57:
58: void
59: SetDefaultFontPath( name)
60: char * name;
61: {
62: int len = strlen( name);
63: int i;
64: /* If there is a previous fontSearchList, free the space that it contains. */
65:
66: for (i=0; i<fontSearchList.npaths; i++)
67: Xfree(fontSearchList.paths[i]);
68: Xfree(fontSearchList.paths);
69: Xfree(fontSearchList.length);
70:
71: if (name[len-1] != '/')
72: len++;
73: fontSearchList.npaths = 1;
74: fontSearchList.length = (int *)Xalloc(sizeof(int));
75: fontSearchList.length[0] = len;
76: fontSearchList.paths = (char **)Xalloc(sizeof(char *));
77: fontSearchList.paths[0] = (char *)Xalloc(len + 1);
78: bcopy(name, fontSearchList.paths[0], len);
79: if (name[strlen(name)-1] != '/')
80: fontSearchList.paths[0][len-1] = '/';
81: fontSearchList.paths[0][len] = '\0';
82: }
83:
84:
85: void
86: FreeFontRecord(pFP)
87: FontPathPtr pFP;
88: {
89: int i;
90: for (i=0; i<pFP->npaths; i++)
91: Xfree(pFP->paths[i]);
92: Xfree(pFP->paths);
93: Xfree(pFP->length);
94: Xfree(pFP);
95: }
96:
97: /*
98: * pnames is a pointer to counted strings, each string long word
99: * aligned
100: */
101: void
102: SetFontPath( npaths, totalLength, countedStrings)
103: int npaths;
104: int totalLength;
105: char * countedStrings;
106: {
107: int i;
108: char * bufPtr = countedStrings;
109: char n, len;
110:
111: if (npaths == 0)
112: {
113: SetDefaultFontPath(defaultFontPath); /* this frees old paths */
114: }
115: else
116: {
117: for (i=0; i<fontSearchList.npaths; i++)
118: Xfree(fontSearchList.paths[i]);
119: Xfree(fontSearchList.paths);
120: Xfree(fontSearchList.length);
121:
122: fontSearchList.length = (int *)Xalloc(npaths * sizeof(int));
123: fontSearchList.paths = (char **)Xalloc(npaths * sizeof(char *));
124: for (i=0; i<npaths; i++)
125: {
126: n = len = *bufPtr;
127: if (bufPtr[n] != '/')
128: len++;
129: fontSearchList.length[i] = len;
130: fontSearchList.paths[i] = (char *) Xalloc(len + 1);
131: bcopy(bufPtr+1, fontSearchList.paths[i], n);
132: if (bufPtr[n] != '/')
133: fontSearchList.paths[i][n] = '/';
134: fontSearchList.paths[i][len] = '\0';
135: bufPtr += n + 1;
136: }
137: fontSearchList.npaths = npaths;
138: }
139: }
140:
141:
142: /*
143: * return value is length in bytes
144: */
145:
146: FontPathPtr
147: GetFontPath()
148: {
149: return( & fontSearchList);
150: }
151:
152: static int
153: match( pat, string)
154: char *pat;
155: char *string;
156: {
157: int ip;
158: Bool matched;
159:
160: for ( ip=0; pat[ip]!='\0'; ip++)
161: {
162: if ( pat[ip] == '*')
163: {
164: matched = FALSE;
165: while (! matched ) /* find where pat & string start to match */
166: {
167: if ( string[ip] == '\0')
168: {
169: if (pat[ip+1] == '\0')
170: return TRUE;
171: break;
172: }
173: while ( ! (matched = match( &pat[ip+1], &string[ip])))
174: {
175: string++;
176: if ( string[0] == '\0')
177: return FALSE;
178: }
179: }
180: if (matched)
181: return TRUE;
182: }
183: else if (string[ip] == '\0')
184: return FALSE;
185: else if (( pat[ip] != '?') && (pat[ip] != string[ip]))
186: return FALSE;
187: }
188: return TRUE;
189: }
190:
191:
192: /*
193: * Make further assumption that '/' is the pathname separator.
194: * Still assume NULL ends strings.
195: */
196: /*
197: * used by OpenFont
198: *
199: * returns length of ppathname.
200: * may set *ppPathname to fname;
201: */
202:
203: int
204: ExpandFontName( ppPathname, lenfname, fname)
205: char **ppPathname;
206: int lenfname;
207: char *fname;
208: {
209: int in;
210: char *fullname = NULL;
211: char *lowername;
212: char *pch;
213:
214: lowername = (char *) Xalloc(lenfname + 5);
215: bzero(lowername, lenfname + 5);
216: strncpy(lowername, fname, lenfname);
217: /* if the name doesn't end in .snf, append that to the name */
218: if((pch = index(lowername, '.')) == NULL ||
219: *(pch + 1) != 's' ||
220: *(pch + 2) != 'n' ||
221: *(pch + 3) != 'f' ||
222: pch + 4 - lowername != lenfname)
223: {
224: strcat(lowername, ".snf");
225: lenfname += 4;
226: }
227:
228:
229: /*
230: * reduce to lower case only
231: */
232: for ( in=0; in<lenfname; in++)
233: if ( isupper( lowername[in]))
234: lowername[in] = tolower( lowername[in]);
235:
236: if (lowername[0] == '/')
237: {
238: if ( access( lowername, R_OK) == 0)
239: {
240: *ppPathname = lowername;
241: return lenfname;
242: }
243: }
244: else
245: {
246: int n, ifp;
247:
248: for ( ifp=0; ifp<fontSearchList.npaths; ifp++)
249: {
250: fullname = (char *) Xrealloc( fullname,
251: n = fontSearchList.length[ifp] + lenfname + 1);
252: strcpy( fullname, fontSearchList.paths[ifp]);
253: strncat( fullname, lowername, lenfname);
254: fullname[n-1] = '\0';
255: if ( access( fullname, R_OK) == 0)
256: {
257: *ppPathname = fullname;
258: Xfree(lowername);
259: return strlen( fullname);
260: }
261: }
262: }
263: Xfree(lowername);
264: Xfree(fullname);
265: *ppPathname = NULL;
266: return 0;
267: }
268:
269: static void
270: SearchDirectory(dname, pat, pFP, limit)
271: char *dname;
272: char *pat;
273: FontPathPtr pFP;
274: int limit;
275: {
276: DIR *dp;
277: struct direct *nextdent;
278: int n, i;
279:
280: dp = opendir( dname);
281: if (dp == NULL)
282: return ;
283: i = pFP->npaths;
284: while ( (nextdent = readdir( dp)) != NULL)
285: {
286: if (i >= limit)
287: break ;
288: if ( match( pat, nextdent->d_name))
289: {
290: pFP->length = (int *)Xrealloc(pFP->length, (i+1)*sizeof(int));
291: pFP->paths = (char **)Xrealloc(pFP->paths, (i+1)*sizeof(char *));
292: pFP->length[i] = n = strlen( nextdent->d_name);
293: pFP->paths[i] = (char *) Xalloc(n);
294: bcopy(nextdent->d_name, pFP->paths[i], n);
295: i = ++pFP->npaths;
296: }
297: }
298: closedir(dp);
299: }
300:
301: /*******************************************************************
302: * ExpandFontPathPattern
303: *
304: * Returns a FontPathPtr with at most max-names, of names of fonts
305: * matching
306: * the pattern. The pattern should use the ASCII encoding, and
307: * upper/lower case does not matter. In the pattern, the '?' character
308: * (octal value 77) will match any single character, and the character '*'
309: * (octal value 52) will match any number of characters. The return
310: * names are in lower case.
311: *
312: * Used only by protocol request ListFonts
313: *******************************************************************/
314:
315:
316: FontPathPtr
317: ExpandFontNamePattern(lenpat, countedPattern, maxNames)
318: int lenpat;
319: char *countedPattern;
320: int maxNames;
321: {
322: char *pattern;
323: int i;
324: FontPathPtr fpr;
325:
326:
327: fpr = (FontPathPtr)Xalloc(sizeof(FontPathRec));
328: fpr->npaths = 0;
329: fpr->length = (int *)NULL;
330: fpr->paths = (char **)NULL;
331:
332: /*
333: * make a pattern which is guaranteed NULL-terminated
334: */
335: pattern = (char *) ALLOCATE_LOCAL( lenpat + 1 + 4);
336: strncpy( pattern, countedPattern, lenpat);
337: pattern[lenpat] = '\0';
338: strcat(pattern, ".snf");
339:
340: /*
341: * find last '/' in pattern, if any
342: */
343: for ( i=lenpat-1; i>=0; i--)
344: if ( pattern[i] == '/')
345: break;
346:
347: if ( i >= 0) /* pattern contains its own dir prefix */
348: {
349: pattern[i] = '\0'; /* break pattern at the last path separator */
350: SearchDirectory(pattern, &pattern[i+1], fpr, maxNames);
351: }
352: else
353: {
354: /*
355: * for each prefix in the font path list
356: */
357: for ( i=0; i<fontSearchList.npaths; i++)
358: {
359: SearchDirectory( fontSearchList.paths[i], pattern, fpr, maxNames);
360: if (fpr->npaths >= maxNames)
361: break;
362: }
363: }
364: DEALLOCATE_LOCAL(pattern);
365: /*
366: * logically strip the ".snf" off the end since the client wants font
367: * names and not file names.
368: */
369: for (i = 0; i < fpr->npaths; i++)
370: fpr->length[i] -= 4;
371: return fpr;
372: }
373:
374:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.