1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman * *
3*b30d1939SAndy Fiddaman * This software is part of the ast package *
4*b30d1939SAndy Fiddaman * Copyright (c) 1985-2011 AT&T Intellectual Property *
5*b30d1939SAndy Fiddaman * and is licensed under the *
6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 *
7*b30d1939SAndy Fiddaman * by AT&T Intellectual Property *
8*b30d1939SAndy Fiddaman * *
9*b30d1939SAndy Fiddaman * A copy of the License is available at *
10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html *
11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12*b30d1939SAndy Fiddaman * *
13*b30d1939SAndy Fiddaman * Information and Software Systems Research *
14*b30d1939SAndy Fiddaman * AT&T Research *
15*b30d1939SAndy Fiddaman * Florham Park NJ *
16*b30d1939SAndy Fiddaman * *
17*b30d1939SAndy Fiddaman * Glenn Fowler <gsf@research.att.com> *
18*b30d1939SAndy Fiddaman * David Korn <dgk@research.att.com> *
19*b30d1939SAndy Fiddaman * Phong Vo <kpv@research.att.com> *
20*b30d1939SAndy Fiddaman * *
21*b30d1939SAndy Fiddaman ***********************************************************************/
22*b30d1939SAndy Fiddaman #pragma prototyped
23*b30d1939SAndy Fiddaman
24*b30d1939SAndy Fiddaman /*
25*b30d1939SAndy Fiddaman * Glenn Fowler
26*b30d1939SAndy Fiddaman * AT&T Research
27*b30d1939SAndy Fiddaman *
28*b30d1939SAndy Fiddaman * mime/mailcap support library
29*b30d1939SAndy Fiddaman */
30*b30d1939SAndy Fiddaman
31*b30d1939SAndy Fiddaman static const char id[] = "\n@(#)$Id: mime library (AT&T Research) 2002-10-29 $\0\n";
32*b30d1939SAndy Fiddaman
33*b30d1939SAndy Fiddaman static const char lib[] = "libast:mime";
34*b30d1939SAndy Fiddaman
35*b30d1939SAndy Fiddaman #include "mimelib.h"
36*b30d1939SAndy Fiddaman
37*b30d1939SAndy Fiddaman typedef struct Att_s
38*b30d1939SAndy Fiddaman {
39*b30d1939SAndy Fiddaman struct Att_s* next;
40*b30d1939SAndy Fiddaman char* name;
41*b30d1939SAndy Fiddaman char* value;
42*b30d1939SAndy Fiddaman } Att_t;
43*b30d1939SAndy Fiddaman
44*b30d1939SAndy Fiddaman typedef struct Cap_s
45*b30d1939SAndy Fiddaman {
46*b30d1939SAndy Fiddaman struct Cap_s* next;
47*b30d1939SAndy Fiddaman unsigned long flags;
48*b30d1939SAndy Fiddaman Att_t att;
49*b30d1939SAndy Fiddaman char* test;
50*b30d1939SAndy Fiddaman char data[1];
51*b30d1939SAndy Fiddaman } Cap_t;
52*b30d1939SAndy Fiddaman
53*b30d1939SAndy Fiddaman typedef struct
54*b30d1939SAndy Fiddaman {
55*b30d1939SAndy Fiddaman Dtlink_t link;
56*b30d1939SAndy Fiddaman Cap_t* cap;
57*b30d1939SAndy Fiddaman Cap_t* pac;
58*b30d1939SAndy Fiddaman char name[1];
59*b30d1939SAndy Fiddaman } Ent_t;
60*b30d1939SAndy Fiddaman
61*b30d1939SAndy Fiddaman typedef struct
62*b30d1939SAndy Fiddaman {
63*b30d1939SAndy Fiddaman char* data;
64*b30d1939SAndy Fiddaman int size;
65*b30d1939SAndy Fiddaman } String_t;
66*b30d1939SAndy Fiddaman
67*b30d1939SAndy Fiddaman typedef struct
68*b30d1939SAndy Fiddaman {
69*b30d1939SAndy Fiddaman char* next;
70*b30d1939SAndy Fiddaman String_t name;
71*b30d1939SAndy Fiddaman String_t value;
72*b30d1939SAndy Fiddaman } Parse_t;
73*b30d1939SAndy Fiddaman
74*b30d1939SAndy Fiddaman typedef struct
75*b30d1939SAndy Fiddaman {
76*b30d1939SAndy Fiddaman const char* pattern;
77*b30d1939SAndy Fiddaman int prefix;
78*b30d1939SAndy Fiddaman Sfio_t* fp;
79*b30d1939SAndy Fiddaman int hit;
80*b30d1939SAndy Fiddaman } Walk_t;
81*b30d1939SAndy Fiddaman
82*b30d1939SAndy Fiddaman /*
83*b30d1939SAndy Fiddaman * convert c to lower case
84*b30d1939SAndy Fiddaman */
85*b30d1939SAndy Fiddaman
86*b30d1939SAndy Fiddaman static int
lower(int c)87*b30d1939SAndy Fiddaman lower(int c)
88*b30d1939SAndy Fiddaman {
89*b30d1939SAndy Fiddaman return isupper(c) ? tolower(c) : c;
90*b30d1939SAndy Fiddaman }
91*b30d1939SAndy Fiddaman
92*b30d1939SAndy Fiddaman /*
93*b30d1939SAndy Fiddaman * Ent_t case insensitive comparf
94*b30d1939SAndy Fiddaman */
95*b30d1939SAndy Fiddaman
96*b30d1939SAndy Fiddaman static int
order(Dt_t * dt,void * a,void * b,Dtdisc_t * disc)97*b30d1939SAndy Fiddaman order(Dt_t* dt, void* a, void* b, Dtdisc_t* disc)
98*b30d1939SAndy Fiddaman {
99*b30d1939SAndy Fiddaman return strcasecmp(a, b);
100*b30d1939SAndy Fiddaman }
101*b30d1939SAndy Fiddaman
102*b30d1939SAndy Fiddaman /*
103*b30d1939SAndy Fiddaman * Cap_t free
104*b30d1939SAndy Fiddaman */
105*b30d1939SAndy Fiddaman
106*b30d1939SAndy Fiddaman static void
dropcap(Cap_t * cap)107*b30d1939SAndy Fiddaman dropcap(Cap_t* cap)
108*b30d1939SAndy Fiddaman {
109*b30d1939SAndy Fiddaman Att_t* att;
110*b30d1939SAndy Fiddaman
111*b30d1939SAndy Fiddaman while (att = cap->att.next)
112*b30d1939SAndy Fiddaman {
113*b30d1939SAndy Fiddaman cap->att.next = att->next;
114*b30d1939SAndy Fiddaman free(att);
115*b30d1939SAndy Fiddaman }
116*b30d1939SAndy Fiddaman free(cap);
117*b30d1939SAndy Fiddaman }
118*b30d1939SAndy Fiddaman
119*b30d1939SAndy Fiddaman /*
120*b30d1939SAndy Fiddaman * Ent_t freef
121*b30d1939SAndy Fiddaman */
122*b30d1939SAndy Fiddaman
123*b30d1939SAndy Fiddaman static void
drop(Dt_t * dt,void * object,Dtdisc_t * disc)124*b30d1939SAndy Fiddaman drop(Dt_t* dt, void* object, Dtdisc_t* disc)
125*b30d1939SAndy Fiddaman {
126*b30d1939SAndy Fiddaman Ent_t* ent = (Ent_t*)object;
127*b30d1939SAndy Fiddaman Cap_t* cap;
128*b30d1939SAndy Fiddaman
129*b30d1939SAndy Fiddaman while (cap = ent->cap)
130*b30d1939SAndy Fiddaman {
131*b30d1939SAndy Fiddaman ent->cap = cap->next;
132*b30d1939SAndy Fiddaman dropcap(cap);
133*b30d1939SAndy Fiddaman }
134*b30d1939SAndy Fiddaman free(ent);
135*b30d1939SAndy Fiddaman }
136*b30d1939SAndy Fiddaman
137*b30d1939SAndy Fiddaman /*
138*b30d1939SAndy Fiddaman * add mime type entry in s to mp
139*b30d1939SAndy Fiddaman */
140*b30d1939SAndy Fiddaman
141*b30d1939SAndy Fiddaman int
mimeset(Mime_t * mp,char * s,unsigned long flags)142*b30d1939SAndy Fiddaman mimeset(Mime_t* mp, char* s, unsigned long flags)
143*b30d1939SAndy Fiddaman {
144*b30d1939SAndy Fiddaman Ent_t* ent;
145*b30d1939SAndy Fiddaman Cap_t* cap;
146*b30d1939SAndy Fiddaman Att_t* att;
147*b30d1939SAndy Fiddaman char* t;
148*b30d1939SAndy Fiddaman char* v;
149*b30d1939SAndy Fiddaman char* k;
150*b30d1939SAndy Fiddaman char* x;
151*b30d1939SAndy Fiddaman Att_t* tta;
152*b30d1939SAndy Fiddaman int q;
153*b30d1939SAndy Fiddaman
154*b30d1939SAndy Fiddaman for (; isspace(*s); s++);
155*b30d1939SAndy Fiddaman if (*s && *s != '#')
156*b30d1939SAndy Fiddaman {
157*b30d1939SAndy Fiddaman cap = 0;
158*b30d1939SAndy Fiddaman for (v = s; *v && *v != ';'; v++)
159*b30d1939SAndy Fiddaman if (isspace(*v) || *v == '/' && *(v + 1) == '*')
160*b30d1939SAndy Fiddaman *v = 0;
161*b30d1939SAndy Fiddaman if (*v)
162*b30d1939SAndy Fiddaman {
163*b30d1939SAndy Fiddaman *v++ = 0;
164*b30d1939SAndy Fiddaman do
165*b30d1939SAndy Fiddaman {
166*b30d1939SAndy Fiddaman for (; isspace(*v); v++);
167*b30d1939SAndy Fiddaman if (cap)
168*b30d1939SAndy Fiddaman {
169*b30d1939SAndy Fiddaman for (t = v; *t && !isspace(*t) && *t != '='; t++);
170*b30d1939SAndy Fiddaman for (k = t; isspace(*t); t++);
171*b30d1939SAndy Fiddaman if (!*t || *t == '=' || *t == ';')
172*b30d1939SAndy Fiddaman {
173*b30d1939SAndy Fiddaman if (*t)
174*b30d1939SAndy Fiddaman while (isspace(*++t));
175*b30d1939SAndy Fiddaman *k = 0;
176*b30d1939SAndy Fiddaman k = v;
177*b30d1939SAndy Fiddaman v = t;
178*b30d1939SAndy Fiddaman }
179*b30d1939SAndy Fiddaman else
180*b30d1939SAndy Fiddaman k = 0;
181*b30d1939SAndy Fiddaman }
182*b30d1939SAndy Fiddaman if (*v == '"')
183*b30d1939SAndy Fiddaman q = *v++;
184*b30d1939SAndy Fiddaman else
185*b30d1939SAndy Fiddaman q = 0;
186*b30d1939SAndy Fiddaman for (t = v; *t; t++)
187*b30d1939SAndy Fiddaman if (*t == '\\')
188*b30d1939SAndy Fiddaman {
189*b30d1939SAndy Fiddaman switch (*(t + 1))
190*b30d1939SAndy Fiddaman {
191*b30d1939SAndy Fiddaman case 0:
192*b30d1939SAndy Fiddaman case '\\':
193*b30d1939SAndy Fiddaman case '%':
194*b30d1939SAndy Fiddaman *t = *(t + 1);
195*b30d1939SAndy Fiddaman break;
196*b30d1939SAndy Fiddaman default:
197*b30d1939SAndy Fiddaman *t = ' ';
198*b30d1939SAndy Fiddaman break;
199*b30d1939SAndy Fiddaman }
200*b30d1939SAndy Fiddaman if (!*++t)
201*b30d1939SAndy Fiddaman break;
202*b30d1939SAndy Fiddaman }
203*b30d1939SAndy Fiddaman else if (*t == q)
204*b30d1939SAndy Fiddaman {
205*b30d1939SAndy Fiddaman *t = ' ';
206*b30d1939SAndy Fiddaman q = 0;
207*b30d1939SAndy Fiddaman }
208*b30d1939SAndy Fiddaman else if (*t == ';' && !q)
209*b30d1939SAndy Fiddaman {
210*b30d1939SAndy Fiddaman *t = ' ';
211*b30d1939SAndy Fiddaman break;
212*b30d1939SAndy Fiddaman }
213*b30d1939SAndy Fiddaman for (; t > v && isspace(*(t - 1)); t--);
214*b30d1939SAndy Fiddaman if (t <= v && (!cap || !k))
215*b30d1939SAndy Fiddaman break;
216*b30d1939SAndy Fiddaman if (!cap)
217*b30d1939SAndy Fiddaman {
218*b30d1939SAndy Fiddaman if (!(cap = newof(0, Cap_t, 1, strlen(v) + 1)))
219*b30d1939SAndy Fiddaman return -1;
220*b30d1939SAndy Fiddaman if (*t)
221*b30d1939SAndy Fiddaman *t++ = 0;
222*b30d1939SAndy Fiddaman tta = &cap->att;
223*b30d1939SAndy Fiddaman tta->name = "default";
224*b30d1939SAndy Fiddaman x = strcopy(tta->value = cap->data, v) + 1;
225*b30d1939SAndy Fiddaman }
226*b30d1939SAndy Fiddaman else if (k)
227*b30d1939SAndy Fiddaman {
228*b30d1939SAndy Fiddaman if (*t)
229*b30d1939SAndy Fiddaman *t++ = 0;
230*b30d1939SAndy Fiddaman if (!(att = newof(0, Att_t, 1, 0)))
231*b30d1939SAndy Fiddaman return -1;
232*b30d1939SAndy Fiddaman x = strcopy(att->name = x, k) + 1;
233*b30d1939SAndy Fiddaman x = strcopy(att->value = x, v) + 1;
234*b30d1939SAndy Fiddaman tta = tta->next = att;
235*b30d1939SAndy Fiddaman if (!strcasecmp(k, "test"))
236*b30d1939SAndy Fiddaman cap->test = att->value;
237*b30d1939SAndy Fiddaman }
238*b30d1939SAndy Fiddaman } while (*(v = t));
239*b30d1939SAndy Fiddaman }
240*b30d1939SAndy Fiddaman ent = (Ent_t*)dtmatch(mp->cap, s);
241*b30d1939SAndy Fiddaman if (cap)
242*b30d1939SAndy Fiddaman {
243*b30d1939SAndy Fiddaman if (ent)
244*b30d1939SAndy Fiddaman {
245*b30d1939SAndy Fiddaman Cap_t* dup;
246*b30d1939SAndy Fiddaman Cap_t* pud;
247*b30d1939SAndy Fiddaman
248*b30d1939SAndy Fiddaman for (pud = 0, dup = ent->cap; dup; pud = dup, dup = dup->next)
249*b30d1939SAndy Fiddaman if (!cap->test && !dup->test || cap->test && dup->test && streq(cap->test, dup->test))
250*b30d1939SAndy Fiddaman {
251*b30d1939SAndy Fiddaman if (flags & MIME_REPLACE)
252*b30d1939SAndy Fiddaman {
253*b30d1939SAndy Fiddaman if (pud)
254*b30d1939SAndy Fiddaman pud->next = cap;
255*b30d1939SAndy Fiddaman else
256*b30d1939SAndy Fiddaman ent->cap = cap;
257*b30d1939SAndy Fiddaman if (!(cap->next = dup->next))
258*b30d1939SAndy Fiddaman ent->pac = cap;
259*b30d1939SAndy Fiddaman cap = dup;
260*b30d1939SAndy Fiddaman }
261*b30d1939SAndy Fiddaman dropcap(cap);
262*b30d1939SAndy Fiddaman return 0;
263*b30d1939SAndy Fiddaman }
264*b30d1939SAndy Fiddaman ent->pac = ent->pac->next = cap;
265*b30d1939SAndy Fiddaman }
266*b30d1939SAndy Fiddaman else if (!(ent = newof(0, Ent_t, 1, strlen(s) + 1)))
267*b30d1939SAndy Fiddaman return -1;
268*b30d1939SAndy Fiddaman else
269*b30d1939SAndy Fiddaman {
270*b30d1939SAndy Fiddaman strcpy(ent->name, s);
271*b30d1939SAndy Fiddaman ent->cap = ent->pac = cap;
272*b30d1939SAndy Fiddaman dtinsert(mp->cap, ent);
273*b30d1939SAndy Fiddaman }
274*b30d1939SAndy Fiddaman }
275*b30d1939SAndy Fiddaman else if (ent && (flags & MIME_REPLACE))
276*b30d1939SAndy Fiddaman dtdelete(mp->cap, ent);
277*b30d1939SAndy Fiddaman }
278*b30d1939SAndy Fiddaman return 0;
279*b30d1939SAndy Fiddaman }
280*b30d1939SAndy Fiddaman
281*b30d1939SAndy Fiddaman /*
282*b30d1939SAndy Fiddaman * load mime type files into mp
283*b30d1939SAndy Fiddaman */
284*b30d1939SAndy Fiddaman
285*b30d1939SAndy Fiddaman int
mimeload(Mime_t * mp,const char * file,unsigned long flags)286*b30d1939SAndy Fiddaman mimeload(Mime_t* mp, const char* file, unsigned long flags)
287*b30d1939SAndy Fiddaman {
288*b30d1939SAndy Fiddaman char* s;
289*b30d1939SAndy Fiddaman char* t;
290*b30d1939SAndy Fiddaman char* e;
291*b30d1939SAndy Fiddaman int n;
292*b30d1939SAndy Fiddaman Sfio_t* fp;
293*b30d1939SAndy Fiddaman
294*b30d1939SAndy Fiddaman if (!(s = (char*)file))
295*b30d1939SAndy Fiddaman {
296*b30d1939SAndy Fiddaman flags |= MIME_LIST;
297*b30d1939SAndy Fiddaman if (!(s = getenv(MIME_FILES_ENV)))
298*b30d1939SAndy Fiddaman s = MIME_FILES;
299*b30d1939SAndy Fiddaman }
300*b30d1939SAndy Fiddaman for (;;)
301*b30d1939SAndy Fiddaman {
302*b30d1939SAndy Fiddaman if (!(flags & MIME_LIST))
303*b30d1939SAndy Fiddaman e = 0;
304*b30d1939SAndy Fiddaman else if (e = strchr(s, ':'))
305*b30d1939SAndy Fiddaman {
306*b30d1939SAndy Fiddaman /*
307*b30d1939SAndy Fiddaman * ok, so ~ won't work for the last list element
308*b30d1939SAndy Fiddaman * we do it for MIME_FILES_ENV anyway
309*b30d1939SAndy Fiddaman */
310*b30d1939SAndy Fiddaman
311*b30d1939SAndy Fiddaman if ((strneq(s, "~/", n = 2) || strneq(s, "$HOME/", n = 6) || strneq(s, "${HOME}/", n = 8)) && (t = getenv("HOME")))
312*b30d1939SAndy Fiddaman {
313*b30d1939SAndy Fiddaman sfputr(mp->buf, t, -1);
314*b30d1939SAndy Fiddaman s += n - 1;
315*b30d1939SAndy Fiddaman }
316*b30d1939SAndy Fiddaman sfwrite(mp->buf, s, e - s);
317*b30d1939SAndy Fiddaman if (!(s = sfstruse(mp->buf)))
318*b30d1939SAndy Fiddaman return -1;
319*b30d1939SAndy Fiddaman }
320*b30d1939SAndy Fiddaman if (fp = tokline(s, SF_READ, NiL))
321*b30d1939SAndy Fiddaman {
322*b30d1939SAndy Fiddaman while (t = sfgetr(fp, '\n', 1))
323*b30d1939SAndy Fiddaman if (mimeset(mp, t, flags))
324*b30d1939SAndy Fiddaman break;
325*b30d1939SAndy Fiddaman sfclose(fp);
326*b30d1939SAndy Fiddaman }
327*b30d1939SAndy Fiddaman else if (!(flags & MIME_LIST))
328*b30d1939SAndy Fiddaman return -1;
329*b30d1939SAndy Fiddaman if (!e)
330*b30d1939SAndy Fiddaman break;
331*b30d1939SAndy Fiddaman s = e + 1;
332*b30d1939SAndy Fiddaman }
333*b30d1939SAndy Fiddaman return 0;
334*b30d1939SAndy Fiddaman }
335*b30d1939SAndy Fiddaman
336*b30d1939SAndy Fiddaman /*
337*b30d1939SAndy Fiddaman * mimelist walker
338*b30d1939SAndy Fiddaman */
339*b30d1939SAndy Fiddaman
340*b30d1939SAndy Fiddaman static int
list(Dt_t * dt,void * object,void * context)341*b30d1939SAndy Fiddaman list(Dt_t* dt, void* object, void* context)
342*b30d1939SAndy Fiddaman {
343*b30d1939SAndy Fiddaman Walk_t* wp = (Walk_t*)context;
344*b30d1939SAndy Fiddaman Ent_t* ent = (Ent_t*)object;
345*b30d1939SAndy Fiddaman Cap_t* cap;
346*b30d1939SAndy Fiddaman Att_t* att;
347*b30d1939SAndy Fiddaman
348*b30d1939SAndy Fiddaman if (!wp->pattern || !strncasecmp(ent->name, wp->pattern, wp->prefix) && (!ent->name[wp->prefix] || ent->name[wp->prefix] == '/'))
349*b30d1939SAndy Fiddaman {
350*b30d1939SAndy Fiddaman wp->hit++;
351*b30d1939SAndy Fiddaman for (cap = ent->cap; cap; cap = cap->next)
352*b30d1939SAndy Fiddaman {
353*b30d1939SAndy Fiddaman sfprintf(wp->fp, "%s", ent->name);
354*b30d1939SAndy Fiddaman for (att = &cap->att; att; att = att->next)
355*b30d1939SAndy Fiddaman {
356*b30d1939SAndy Fiddaman sfprintf(wp->fp, "\n\t");
357*b30d1939SAndy Fiddaman if (att != &cap->att)
358*b30d1939SAndy Fiddaman {
359*b30d1939SAndy Fiddaman sfprintf(wp->fp, "%s", att->name);
360*b30d1939SAndy Fiddaman if (*att->value)
361*b30d1939SAndy Fiddaman sfprintf(wp->fp, " = ");
362*b30d1939SAndy Fiddaman }
363*b30d1939SAndy Fiddaman sfputr(wp->fp, att->value, -1);
364*b30d1939SAndy Fiddaman }
365*b30d1939SAndy Fiddaman sfprintf(wp->fp, "\n");
366*b30d1939SAndy Fiddaman }
367*b30d1939SAndy Fiddaman }
368*b30d1939SAndy Fiddaman return 0;
369*b30d1939SAndy Fiddaman }
370*b30d1939SAndy Fiddaman
371*b30d1939SAndy Fiddaman /*
372*b30d1939SAndy Fiddaman * find entry matching type
373*b30d1939SAndy Fiddaman * if exact match fails then left and right x- and right version number
374*b30d1939SAndy Fiddaman * permutations are attempted
375*b30d1939SAndy Fiddaman */
376*b30d1939SAndy Fiddaman
377*b30d1939SAndy Fiddaman static Ent_t*
find(Mime_t * mp,const char * type)378*b30d1939SAndy Fiddaman find(Mime_t* mp, const char* type)
379*b30d1939SAndy Fiddaman {
380*b30d1939SAndy Fiddaman char* lp;
381*b30d1939SAndy Fiddaman char* rp;
382*b30d1939SAndy Fiddaman char* rb;
383*b30d1939SAndy Fiddaman char* rv;
384*b30d1939SAndy Fiddaman int rc;
385*b30d1939SAndy Fiddaman int i;
386*b30d1939SAndy Fiddaman char* s;
387*b30d1939SAndy Fiddaman Ent_t* ent;
388*b30d1939SAndy Fiddaman char buf[256];
389*b30d1939SAndy Fiddaman
390*b30d1939SAndy Fiddaman static const char* prefix[] = { "", "", "x-", "x-", "" };
391*b30d1939SAndy Fiddaman
392*b30d1939SAndy Fiddaman if ((ent = (Ent_t*)dtmatch(mp->cap, type)) ||
393*b30d1939SAndy Fiddaman !(rp = strchr(lp = (char*)type, '/')) ||
394*b30d1939SAndy Fiddaman strlen(lp) >= sizeof(buf))
395*b30d1939SAndy Fiddaman return ent;
396*b30d1939SAndy Fiddaman strcpy(buf, type);
397*b30d1939SAndy Fiddaman rp = buf + (rp - lp);
398*b30d1939SAndy Fiddaman *rp++ = 0;
399*b30d1939SAndy Fiddaman if (*rp == 'x' && *(rp + 1) == '-')
400*b30d1939SAndy Fiddaman rp += 2;
401*b30d1939SAndy Fiddaman lp = buf;
402*b30d1939SAndy Fiddaman if (*lp == 'x' && *(lp + 1) == '-')
403*b30d1939SAndy Fiddaman lp += 2;
404*b30d1939SAndy Fiddaman rb = rp;
405*b30d1939SAndy Fiddaman for (rv = rp + strlen(rp); rv > rp && (isdigit(*(rv - 1)) || *(rv - 1) == '.'); rv--);
406*b30d1939SAndy Fiddaman rc = *rv;
407*b30d1939SAndy Fiddaman do
408*b30d1939SAndy Fiddaman {
409*b30d1939SAndy Fiddaman rp = rb;
410*b30d1939SAndy Fiddaman do
411*b30d1939SAndy Fiddaman {
412*b30d1939SAndy Fiddaman for (i = 0; i < elementsof(prefix) - 1; i++)
413*b30d1939SAndy Fiddaman {
414*b30d1939SAndy Fiddaman sfprintf(mp->buf, "%s%s/%s%s", prefix[i], lp, prefix[i + 1], rp);
415*b30d1939SAndy Fiddaman if (!(s = sfstruse(mp->buf)))
416*b30d1939SAndy Fiddaman return 0;
417*b30d1939SAndy Fiddaman if (ent = (Ent_t*)dtmatch(mp->cap, s))
418*b30d1939SAndy Fiddaman return ent;
419*b30d1939SAndy Fiddaman if (rc)
420*b30d1939SAndy Fiddaman {
421*b30d1939SAndy Fiddaman *rv = 0;
422*b30d1939SAndy Fiddaman sfprintf(mp->buf, "%s%s/%s%s", prefix[i], lp, prefix[i + 1], rp);
423*b30d1939SAndy Fiddaman if (!(s = sfstruse(mp->buf)))
424*b30d1939SAndy Fiddaman return 0;
425*b30d1939SAndy Fiddaman if (ent = (Ent_t*)dtmatch(mp->cap, s))
426*b30d1939SAndy Fiddaman return ent;
427*b30d1939SAndy Fiddaman *rv = rc;
428*b30d1939SAndy Fiddaman }
429*b30d1939SAndy Fiddaman }
430*b30d1939SAndy Fiddaman while (*rp && *rp++ != '-');
431*b30d1939SAndy Fiddaman } while (*rp);
432*b30d1939SAndy Fiddaman while (*lp && *lp++ != '-');
433*b30d1939SAndy Fiddaman } while (*lp);
434*b30d1939SAndy Fiddaman return (Ent_t*)dtmatch(mp->cap, buf);
435*b30d1939SAndy Fiddaman }
436*b30d1939SAndy Fiddaman
437*b30d1939SAndy Fiddaman /*
438*b30d1939SAndy Fiddaman * list mime <type,data> for pat on fp
439*b30d1939SAndy Fiddaman */
440*b30d1939SAndy Fiddaman
441*b30d1939SAndy Fiddaman int
mimelist(Mime_t * mp,Sfio_t * fp,const char * pattern)442*b30d1939SAndy Fiddaman mimelist(Mime_t* mp, Sfio_t* fp, const char* pattern)
443*b30d1939SAndy Fiddaman {
444*b30d1939SAndy Fiddaman Ent_t* ent;
445*b30d1939SAndy Fiddaman Walk_t ws;
446*b30d1939SAndy Fiddaman
447*b30d1939SAndy Fiddaman ws.fp = fp;
448*b30d1939SAndy Fiddaman ws.hit = 0;
449*b30d1939SAndy Fiddaman ws.prefix = 0;
450*b30d1939SAndy Fiddaman if (ws.pattern = pattern)
451*b30d1939SAndy Fiddaman {
452*b30d1939SAndy Fiddaman while (*pattern && *pattern++ != '/');
453*b30d1939SAndy Fiddaman if (!*pattern || *pattern == '*' && !*(pattern + 1))
454*b30d1939SAndy Fiddaman ws.prefix = pattern - ws.pattern;
455*b30d1939SAndy Fiddaman else if (ent = find(mp, ws.pattern))
456*b30d1939SAndy Fiddaman {
457*b30d1939SAndy Fiddaman ws.pattern = 0;
458*b30d1939SAndy Fiddaman list(mp->cap, ent, &ws);
459*b30d1939SAndy Fiddaman return ws.hit;
460*b30d1939SAndy Fiddaman }
461*b30d1939SAndy Fiddaman }
462*b30d1939SAndy Fiddaman dtwalk(mp->cap, list, &ws);
463*b30d1939SAndy Fiddaman return ws.hit;
464*b30d1939SAndy Fiddaman }
465*b30d1939SAndy Fiddaman
466*b30d1939SAndy Fiddaman /*
467*b30d1939SAndy Fiddaman * get next arg in pp
468*b30d1939SAndy Fiddaman * 0 returned if no more args
469*b30d1939SAndy Fiddaman */
470*b30d1939SAndy Fiddaman
471*b30d1939SAndy Fiddaman static int
arg(Parse_t * pp,int first)472*b30d1939SAndy Fiddaman arg(Parse_t* pp, int first)
473*b30d1939SAndy Fiddaman {
474*b30d1939SAndy Fiddaman char* s;
475*b30d1939SAndy Fiddaman int c;
476*b30d1939SAndy Fiddaman int q;
477*b30d1939SAndy Fiddaman int x;
478*b30d1939SAndy Fiddaman
479*b30d1939SAndy Fiddaman for (s = pp->next; isspace(*s) && *s != '\n'; s++);
480*b30d1939SAndy Fiddaman if (!*s || *s == '\n')
481*b30d1939SAndy Fiddaman {
482*b30d1939SAndy Fiddaman pp->next = s;
483*b30d1939SAndy Fiddaman return 0;
484*b30d1939SAndy Fiddaman }
485*b30d1939SAndy Fiddaman pp->name.data = s;
486*b30d1939SAndy Fiddaman pp->value.data = 0;
487*b30d1939SAndy Fiddaman q = 0;
488*b30d1939SAndy Fiddaman x = 0;
489*b30d1939SAndy Fiddaman while ((c = *s++) && c != ';' && c != '\n')
490*b30d1939SAndy Fiddaman {
491*b30d1939SAndy Fiddaman if (c == '"')
492*b30d1939SAndy Fiddaman {
493*b30d1939SAndy Fiddaman q = 1;
494*b30d1939SAndy Fiddaman if (pp->value.data)
495*b30d1939SAndy Fiddaman {
496*b30d1939SAndy Fiddaman pp->value.data = s;
497*b30d1939SAndy Fiddaman if (x)
498*b30d1939SAndy Fiddaman x = -1;
499*b30d1939SAndy Fiddaman else
500*b30d1939SAndy Fiddaman x = 1;
501*b30d1939SAndy Fiddaman }
502*b30d1939SAndy Fiddaman else if (!x && pp->name.data == (s - 1))
503*b30d1939SAndy Fiddaman {
504*b30d1939SAndy Fiddaman x = 1;
505*b30d1939SAndy Fiddaman pp->name.data = s;
506*b30d1939SAndy Fiddaman }
507*b30d1939SAndy Fiddaman do
508*b30d1939SAndy Fiddaman {
509*b30d1939SAndy Fiddaman if (!(c = *s++) || c == '\n')
510*b30d1939SAndy Fiddaman {
511*b30d1939SAndy Fiddaman s--;
512*b30d1939SAndy Fiddaman break;
513*b30d1939SAndy Fiddaman }
514*b30d1939SAndy Fiddaman } while (c != '"');
515*b30d1939SAndy Fiddaman if (first < 0 || x > 0)
516*b30d1939SAndy Fiddaman {
517*b30d1939SAndy Fiddaman c = ';';
518*b30d1939SAndy Fiddaman break;
519*b30d1939SAndy Fiddaman }
520*b30d1939SAndy Fiddaman }
521*b30d1939SAndy Fiddaman else if (c == '=' && !first)
522*b30d1939SAndy Fiddaman {
523*b30d1939SAndy Fiddaman first = 1;
524*b30d1939SAndy Fiddaman pp->name.size = s - pp->name.data - 1;
525*b30d1939SAndy Fiddaman pp->value.data = s;
526*b30d1939SAndy Fiddaman }
527*b30d1939SAndy Fiddaman else if (first >= 0 && isspace(c))
528*b30d1939SAndy Fiddaman break;
529*b30d1939SAndy Fiddaman }
530*b30d1939SAndy Fiddaman pp->next = s - (c != ';');
531*b30d1939SAndy Fiddaman if (first >= 0 || !q)
532*b30d1939SAndy Fiddaman for (s--; s > pp->name.data && isspace(*(s - 1)); s--);
533*b30d1939SAndy Fiddaman if (pp->value.data)
534*b30d1939SAndy Fiddaman pp->value.size = s - pp->value.data - (q && first < 0);
535*b30d1939SAndy Fiddaman else
536*b30d1939SAndy Fiddaman {
537*b30d1939SAndy Fiddaman pp->value.size = 0;
538*b30d1939SAndy Fiddaman pp->name.size = s - pp->name.data - (q && first < 0);
539*b30d1939SAndy Fiddaman }
540*b30d1939SAndy Fiddaman if (first >= 0 && pp->name.size > 0 && pp->name.data[pp->name.size - 1] == ':')
541*b30d1939SAndy Fiddaman return 0;
542*b30d1939SAndy Fiddaman return pp->name.size > 0;
543*b30d1939SAndy Fiddaman }
544*b30d1939SAndy Fiddaman
545*b30d1939SAndy Fiddaman /*
546*b30d1939SAndy Fiddaman * low level for mimeview()
547*b30d1939SAndy Fiddaman */
548*b30d1939SAndy Fiddaman
549*b30d1939SAndy Fiddaman static char*
expand(Mime_t * mp,char * s,const char * name,const char * type,const char * opts)550*b30d1939SAndy Fiddaman expand(Mime_t* mp, char* s, const char* name, const char* type, const char* opts)
551*b30d1939SAndy Fiddaman {
552*b30d1939SAndy Fiddaman char* t;
553*b30d1939SAndy Fiddaman char* v;
554*b30d1939SAndy Fiddaman int c;
555*b30d1939SAndy Fiddaman int e;
556*b30d1939SAndy Fiddaman int n;
557*b30d1939SAndy Fiddaman Parse_t pp;
558*b30d1939SAndy Fiddaman
559*b30d1939SAndy Fiddaman mp->disc->flags |= MIME_PIPE;
560*b30d1939SAndy Fiddaman for (;;)
561*b30d1939SAndy Fiddaman {
562*b30d1939SAndy Fiddaman switch (c = *s++)
563*b30d1939SAndy Fiddaman {
564*b30d1939SAndy Fiddaman case 0:
565*b30d1939SAndy Fiddaman case '\n':
566*b30d1939SAndy Fiddaman break;
567*b30d1939SAndy Fiddaman case '%':
568*b30d1939SAndy Fiddaman if ((c = *s++) == '{' && (e = '}') || c == '(' && (e = ')'))
569*b30d1939SAndy Fiddaman {
570*b30d1939SAndy Fiddaman for (t = s; *s && *s != e; s++);
571*b30d1939SAndy Fiddaman n = s - t;
572*b30d1939SAndy Fiddaman switch (*s)
573*b30d1939SAndy Fiddaman {
574*b30d1939SAndy Fiddaman case '}':
575*b30d1939SAndy Fiddaman s++;
576*b30d1939SAndy Fiddaman c = '{';
577*b30d1939SAndy Fiddaman break;
578*b30d1939SAndy Fiddaman case ')':
579*b30d1939SAndy Fiddaman s++;
580*b30d1939SAndy Fiddaman if (c = *s)
581*b30d1939SAndy Fiddaman s++;
582*b30d1939SAndy Fiddaman break;
583*b30d1939SAndy Fiddaman }
584*b30d1939SAndy Fiddaman }
585*b30d1939SAndy Fiddaman else
586*b30d1939SAndy Fiddaman t = 0;
587*b30d1939SAndy Fiddaman switch (c)
588*b30d1939SAndy Fiddaman {
589*b30d1939SAndy Fiddaman case 's':
590*b30d1939SAndy Fiddaman v = (char*)name;
591*b30d1939SAndy Fiddaman mp->disc->flags &= ~MIME_PIPE;
592*b30d1939SAndy Fiddaman break;
593*b30d1939SAndy Fiddaman case 't':
594*b30d1939SAndy Fiddaman v = (char*)type;
595*b30d1939SAndy Fiddaman break;
596*b30d1939SAndy Fiddaman case '{':
597*b30d1939SAndy Fiddaman for (t = s; *s && *s != '}'; s++);
598*b30d1939SAndy Fiddaman if (*s && (c = s++ - t) && (pp.next = (char*)opts))
599*b30d1939SAndy Fiddaman while (arg(&pp, 0))
600*b30d1939SAndy Fiddaman if (pp.name.size == c && !strncasecmp(pp.name.data, t, c))
601*b30d1939SAndy Fiddaman {
602*b30d1939SAndy Fiddaman if (pp.value.size)
603*b30d1939SAndy Fiddaman sfwrite(mp->buf, pp.value.data, pp.value.size);
604*b30d1939SAndy Fiddaman break;
605*b30d1939SAndy Fiddaman }
606*b30d1939SAndy Fiddaman continue;
607*b30d1939SAndy Fiddaman default:
608*b30d1939SAndy Fiddaman sfputc(mp->buf, c);
609*b30d1939SAndy Fiddaman continue;
610*b30d1939SAndy Fiddaman }
611*b30d1939SAndy Fiddaman if (v && *v)
612*b30d1939SAndy Fiddaman n = strlen(v);
613*b30d1939SAndy Fiddaman else if (t)
614*b30d1939SAndy Fiddaman v = t;
615*b30d1939SAndy Fiddaman else
616*b30d1939SAndy Fiddaman continue;
617*b30d1939SAndy Fiddaman sfputr(mp->buf, fmtquote(v, 0, 0, n, FMT_SHELL), -1);
618*b30d1939SAndy Fiddaman continue;
619*b30d1939SAndy Fiddaman default:
620*b30d1939SAndy Fiddaman sfputc(mp->buf, c);
621*b30d1939SAndy Fiddaman continue;
622*b30d1939SAndy Fiddaman }
623*b30d1939SAndy Fiddaman break;
624*b30d1939SAndy Fiddaman }
625*b30d1939SAndy Fiddaman return sfstruse(mp->buf);
626*b30d1939SAndy Fiddaman }
627*b30d1939SAndy Fiddaman
628*b30d1939SAndy Fiddaman /*
629*b30d1939SAndy Fiddaman * return expanded command/path/value for <view,name,type,opts>
630*b30d1939SAndy Fiddaman * return value valid until next mime*() call
631*b30d1939SAndy Fiddaman */
632*b30d1939SAndy Fiddaman
633*b30d1939SAndy Fiddaman char*
mimeview(Mime_t * mp,const char * view,const char * name,const char * type,const char * opts)634*b30d1939SAndy Fiddaman mimeview(Mime_t* mp, const char* view, const char* name, const char* type, const char* opts)
635*b30d1939SAndy Fiddaman {
636*b30d1939SAndy Fiddaman Ent_t* ent;
637*b30d1939SAndy Fiddaman Cap_t* cap;
638*b30d1939SAndy Fiddaman Att_t* att;
639*b30d1939SAndy Fiddaman char* s;
640*b30d1939SAndy Fiddaman int c;
641*b30d1939SAndy Fiddaman
642*b30d1939SAndy Fiddaman if (ent = find(mp, type))
643*b30d1939SAndy Fiddaman {
644*b30d1939SAndy Fiddaman cap = ent->cap;
645*b30d1939SAndy Fiddaman if (!view || strcasecmp(view, "test"))
646*b30d1939SAndy Fiddaman while (s = cap->test)
647*b30d1939SAndy Fiddaman {
648*b30d1939SAndy Fiddaman if (s = expand(mp, s, name, type, opts))
649*b30d1939SAndy Fiddaman {
650*b30d1939SAndy Fiddaman Parse_t a1;
651*b30d1939SAndy Fiddaman Parse_t a2;
652*b30d1939SAndy Fiddaman Parse_t a3;
653*b30d1939SAndy Fiddaman Parse_t a4;
654*b30d1939SAndy Fiddaman
655*b30d1939SAndy Fiddaman /*
656*b30d1939SAndy Fiddaman * try to do a few common cases here
657*b30d1939SAndy Fiddaman * mailcap consistency is a winning
658*b30d1939SAndy Fiddaman * strategy
659*b30d1939SAndy Fiddaman */
660*b30d1939SAndy Fiddaman
661*b30d1939SAndy Fiddaman a1.next = s;
662*b30d1939SAndy Fiddaman if (arg(&a1, -1))
663*b30d1939SAndy Fiddaman {
664*b30d1939SAndy Fiddaman if ((c = *a1.name.data == '!') && --a1.name.size <= 0 && !arg(&a1, -1))
665*b30d1939SAndy Fiddaman goto lose;
666*b30d1939SAndy Fiddaman if (a1.name.size == 6 && strneq(a1.name.data, "strcmp", 6) || a1.name.size == 10 && strneq(a1.name.data, "strcasecmp", 10))
667*b30d1939SAndy Fiddaman {
668*b30d1939SAndy Fiddaman a2.next = a1.next;
669*b30d1939SAndy Fiddaman if (!arg(&a2, -1))
670*b30d1939SAndy Fiddaman goto lose;
671*b30d1939SAndy Fiddaman a3.next = a2.next;
672*b30d1939SAndy Fiddaman if (!arg(&a3, -1))
673*b30d1939SAndy Fiddaman goto lose;
674*b30d1939SAndy Fiddaman if (a2.name.size != a3.name.size)
675*b30d1939SAndy Fiddaman c ^= 0;
676*b30d1939SAndy Fiddaman else c ^= (a1.name.size == 6 ? strncmp : strncasecmp)(a2.name.data, a3.name.data, a2.name.size) == 0;
677*b30d1939SAndy Fiddaman if (c)
678*b30d1939SAndy Fiddaman break;
679*b30d1939SAndy Fiddaman goto skip;
680*b30d1939SAndy Fiddaman }
681*b30d1939SAndy Fiddaman else if (a1.name.size == 4 && strneq(a1.name.data, "test", 4))
682*b30d1939SAndy Fiddaman {
683*b30d1939SAndy Fiddaman if (!arg(&a1, -1))
684*b30d1939SAndy Fiddaman goto lose;
685*b30d1939SAndy Fiddaman a2.next = a1.next;
686*b30d1939SAndy Fiddaman if (!arg(&a2, -1) || a2.name.size > 2 || a2.name.size == 1 && *a2.name.data != '=' || a2.name.size == 2 && (!strneq(a1.name.data, "!=", 2) || !strneq(a2.name.data, "==", 2)))
687*b30d1939SAndy Fiddaman goto lose;
688*b30d1939SAndy Fiddaman a3.next = a2.next;
689*b30d1939SAndy Fiddaman if (!arg(&a3, -1))
690*b30d1939SAndy Fiddaman goto lose;
691*b30d1939SAndy Fiddaman if (*a3.name.data == '`' && *(a3.name.data + a3.name.size - 1) == '`')
692*b30d1939SAndy Fiddaman {
693*b30d1939SAndy Fiddaman a4 = a3;
694*b30d1939SAndy Fiddaman a3 = a1;
695*b30d1939SAndy Fiddaman a1 = a4;
696*b30d1939SAndy Fiddaman }
697*b30d1939SAndy Fiddaman if (*a1.name.data == '`' && *(a1.name.data + a1.name.size - 1) == '`')
698*b30d1939SAndy Fiddaman {
699*b30d1939SAndy Fiddaman a1.next = a1.name.data + 1;
700*b30d1939SAndy Fiddaman if (!arg(&a1, -1) || a1.name.size != 4 || !strneq(a1.name.data, "echo", 4) || !arg(&a1, -1))
701*b30d1939SAndy Fiddaman goto lose;
702*b30d1939SAndy Fiddaman a4.next = a1.next;
703*b30d1939SAndy Fiddaman if (!arg(&a4, 1) || a4.name.size < 21 || !strneq(a4.name.data, "| tr '[A-Z]' '[a-z]'`", 21))
704*b30d1939SAndy Fiddaman goto lose;
705*b30d1939SAndy Fiddaman }
706*b30d1939SAndy Fiddaman else
707*b30d1939SAndy Fiddaman a4.name.size = 0;
708*b30d1939SAndy Fiddaman c = *a2.name.data == '!';
709*b30d1939SAndy Fiddaman if (a1.name.size != a3.name.size)
710*b30d1939SAndy Fiddaman c ^= 0;
711*b30d1939SAndy Fiddaman else c ^= (a4.name.size ? strncasecmp : strncmp)(a1.name.data, a3.name.data, a1.name.size) == 0;
712*b30d1939SAndy Fiddaman if (c)
713*b30d1939SAndy Fiddaman break;
714*b30d1939SAndy Fiddaman goto skip;
715*b30d1939SAndy Fiddaman }
716*b30d1939SAndy Fiddaman }
717*b30d1939SAndy Fiddaman lose:
718*b30d1939SAndy Fiddaman if (!system(s))
719*b30d1939SAndy Fiddaman break;
720*b30d1939SAndy Fiddaman }
721*b30d1939SAndy Fiddaman skip:
722*b30d1939SAndy Fiddaman if (!(cap = cap->next))
723*b30d1939SAndy Fiddaman return 0;
724*b30d1939SAndy Fiddaman }
725*b30d1939SAndy Fiddaman att = &cap->att;
726*b30d1939SAndy Fiddaman if (view && *view && !streq(view, "-"))
727*b30d1939SAndy Fiddaman while (strcasecmp(view, att->name))
728*b30d1939SAndy Fiddaman if (!(att = att->next))
729*b30d1939SAndy Fiddaman return 0;
730*b30d1939SAndy Fiddaman return expand(mp, att->value, name, type, opts);
731*b30d1939SAndy Fiddaman }
732*b30d1939SAndy Fiddaman return 0;
733*b30d1939SAndy Fiddaman }
734*b30d1939SAndy Fiddaman
735*b30d1939SAndy Fiddaman /*
736*b30d1939SAndy Fiddaman * lower case identifier prefix strcmp
737*b30d1939SAndy Fiddaman * if e!=0 then it will point to the next char after the match
738*b30d1939SAndy Fiddaman */
739*b30d1939SAndy Fiddaman
740*b30d1939SAndy Fiddaman int
mimecmp(const char * s,const char * v,char ** e)741*b30d1939SAndy Fiddaman mimecmp(const char* s, const char* v, char** e)
742*b30d1939SAndy Fiddaman {
743*b30d1939SAndy Fiddaman int n;
744*b30d1939SAndy Fiddaman
745*b30d1939SAndy Fiddaman while (isalnum(*v) || *v == *s && (*v == '_' || *v == '-' || *v == '/'))
746*b30d1939SAndy Fiddaman if (n = lower(*s++) - lower(*v++))
747*b30d1939SAndy Fiddaman return n;
748*b30d1939SAndy Fiddaman if (!isalnum(*s) && *s != '_' && *s != '-')
749*b30d1939SAndy Fiddaman {
750*b30d1939SAndy Fiddaman if (e)
751*b30d1939SAndy Fiddaman *e = (char*)s;
752*b30d1939SAndy Fiddaman return 0;
753*b30d1939SAndy Fiddaman }
754*b30d1939SAndy Fiddaman return lower(*s) - lower(*v);
755*b30d1939SAndy Fiddaman }
756*b30d1939SAndy Fiddaman
757*b30d1939SAndy Fiddaman static int
_mimecmp(const char * s,const char * v)758*b30d1939SAndy Fiddaman _mimecmp(const char* s, const char* v)
759*b30d1939SAndy Fiddaman {
760*b30d1939SAndy Fiddaman return (mimecmp(s, v, NULL));
761*b30d1939SAndy Fiddaman }
762*b30d1939SAndy Fiddaman
763*b30d1939SAndy Fiddaman /*
764*b30d1939SAndy Fiddaman * parse mime headers in strsearch(tab,num,siz) from s
765*b30d1939SAndy Fiddaman * return >0 if mime header consumed
766*b30d1939SAndy Fiddaman */
767*b30d1939SAndy Fiddaman
768*b30d1939SAndy Fiddaman int
mimehead(Mime_t * mp,void * tab,size_t num,size_t siz,char * s)769*b30d1939SAndy Fiddaman mimehead(Mime_t* mp, void* tab, size_t num, size_t siz, char* s)
770*b30d1939SAndy Fiddaman {
771*b30d1939SAndy Fiddaman void* p;
772*b30d1939SAndy Fiddaman char* e;
773*b30d1939SAndy Fiddaman Parse_t pp;
774*b30d1939SAndy Fiddaman Mimevalue_f set;
775*b30d1939SAndy Fiddaman
776*b30d1939SAndy Fiddaman set = mp->disc->valuef;
777*b30d1939SAndy Fiddaman if (!strncasecmp(s, "original-", 9))
778*b30d1939SAndy Fiddaman s += 9;
779*b30d1939SAndy Fiddaman if (!strncasecmp(s, "content-", 8))
780*b30d1939SAndy Fiddaman {
781*b30d1939SAndy Fiddaman s += 8;
782*b30d1939SAndy Fiddaman if ((p = strsearch(tab, num, siz, _mimecmp, s, &e)) && *e == ':')
783*b30d1939SAndy Fiddaman {
784*b30d1939SAndy Fiddaman pp.next = e + 1;
785*b30d1939SAndy Fiddaman if (arg(&pp, 1))
786*b30d1939SAndy Fiddaman {
787*b30d1939SAndy Fiddaman if ((*set)(mp, p, pp.name.data, pp.name.size, mp->disc))
788*b30d1939SAndy Fiddaman return 0;
789*b30d1939SAndy Fiddaman while (arg(&pp, 0))
790*b30d1939SAndy Fiddaman if (pp.value.size &&
791*b30d1939SAndy Fiddaman (p = strsearch(tab, num, siz, _mimecmp, pp.name.data, &e)) &&
792*b30d1939SAndy Fiddaman (*set)(mp, p, pp.value.data, pp.value.size, mp->disc))
793*b30d1939SAndy Fiddaman return 0;
794*b30d1939SAndy Fiddaman return 1;
795*b30d1939SAndy Fiddaman }
796*b30d1939SAndy Fiddaman }
797*b30d1939SAndy Fiddaman else if (strchr(s, ':'))
798*b30d1939SAndy Fiddaman return 1;
799*b30d1939SAndy Fiddaman }
800*b30d1939SAndy Fiddaman return !strncasecmp(s, "x-", 2);
801*b30d1939SAndy Fiddaman }
802*b30d1939SAndy Fiddaman
803*b30d1939SAndy Fiddaman /*
804*b30d1939SAndy Fiddaman * open a mime library handle
805*b30d1939SAndy Fiddaman */
806*b30d1939SAndy Fiddaman
807*b30d1939SAndy Fiddaman Mime_t*
mimeopen(Mimedisc_t * disc)808*b30d1939SAndy Fiddaman mimeopen(Mimedisc_t* disc)
809*b30d1939SAndy Fiddaman {
810*b30d1939SAndy Fiddaman Mime_t* mp;
811*b30d1939SAndy Fiddaman
812*b30d1939SAndy Fiddaman if (!(mp = newof(0, Mime_t, 1, 0)))
813*b30d1939SAndy Fiddaman return 0;
814*b30d1939SAndy Fiddaman mp->id = lib;
815*b30d1939SAndy Fiddaman mp->disc = disc;
816*b30d1939SAndy Fiddaman mp->dict.key = offsetof(Ent_t, name);
817*b30d1939SAndy Fiddaman mp->dict.comparf = order;
818*b30d1939SAndy Fiddaman mp->dict.freef = drop;
819*b30d1939SAndy Fiddaman if (!(mp->buf = sfstropen()) || !(mp->cap = dtopen(&mp->dict, Dtoset)))
820*b30d1939SAndy Fiddaman {
821*b30d1939SAndy Fiddaman mimeclose(mp);
822*b30d1939SAndy Fiddaman return 0;
823*b30d1939SAndy Fiddaman }
824*b30d1939SAndy Fiddaman return mp;
825*b30d1939SAndy Fiddaman }
826*b30d1939SAndy Fiddaman
827*b30d1939SAndy Fiddaman /*
828*b30d1939SAndy Fiddaman * close a mimeopen() handle
829*b30d1939SAndy Fiddaman */
830*b30d1939SAndy Fiddaman
831*b30d1939SAndy Fiddaman int
mimeclose(Mime_t * mp)832*b30d1939SAndy Fiddaman mimeclose(Mime_t* mp)
833*b30d1939SAndy Fiddaman {
834*b30d1939SAndy Fiddaman if (mp)
835*b30d1939SAndy Fiddaman {
836*b30d1939SAndy Fiddaman if (mp->buf)
837*b30d1939SAndy Fiddaman sfclose(mp->buf);
838*b30d1939SAndy Fiddaman if (mp->cap)
839*b30d1939SAndy Fiddaman dtclose(mp->cap);
840*b30d1939SAndy Fiddaman if (mp->freef)
841*b30d1939SAndy Fiddaman (*mp->freef)(mp);
842*b30d1939SAndy Fiddaman free(mp);
843*b30d1939SAndy Fiddaman }
844*b30d1939SAndy Fiddaman return 0;
845*b30d1939SAndy Fiddaman }
846