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