xref: /onnv-gate/usr/src/lib/libast/common/port/astlicense.c (revision 4887:feebf9260c2e)
1*4887Schin /***********************************************************************
2*4887Schin *                                                                      *
3*4887Schin *               This software is part of the ast package               *
4*4887Schin *           Copyright (c) 1985-2007 AT&T Knowledge Ventures            *
5*4887Schin *                      and is licensed under the                       *
6*4887Schin *                  Common Public License, Version 1.0                  *
7*4887Schin *                      by AT&T Knowledge Ventures                      *
8*4887Schin *                                                                      *
9*4887Schin *                A copy of the License is available at                 *
10*4887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
11*4887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*4887Schin *                                                                      *
13*4887Schin *              Information and Software Systems Research               *
14*4887Schin *                            AT&T Research                             *
15*4887Schin *                           Florham Park NJ                            *
16*4887Schin *                                                                      *
17*4887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
18*4887Schin *                  David Korn <dgk@research.att.com>                   *
19*4887Schin *                   Phong Vo <kpv@research.att.com>                    *
20*4887Schin *                                                                      *
21*4887Schin ***********************************************************************/
22*4887Schin #pragma prototyped
23*4887Schin 
24*4887Schin /*
25*4887Schin  * Glenn Fowler
26*4887Schin  * AT&T Research
27*4887Schin  *
28*4887Schin  * generate a license comment -- see proto(1)
29*4887Schin  *
30*4887Schin  * NOTE: coded for minimal library dependence
31*4887Schin  *	 not so for the legal department
32*4887Schin  */
33*4887Schin 
34*4887Schin #ifndef	_PPLIB_H
35*4887Schin #include <ast.h>
36*4887Schin #include <time.h>
37*4887Schin #endif
38*4887Schin 
39*4887Schin #undef	copy
40*4887Schin #undef	BSD			/* guess who defines this */
41*4887Schin #undef	END
42*4887Schin #undef	INLINE
43*4887Schin #undef	TEST
44*4887Schin #undef	VERBOSE
45*4887Schin 
46*4887Schin #define NONE			0
47*4887Schin #define INLINE			1
48*4887Schin #define TEST			2
49*4887Schin #define VERBOSE			3
50*4887Schin #define USAGE			4
51*4887Schin #define OPEN			5
52*4887Schin #define CPL			6
53*4887Schin #define BSD			7
54*4887Schin #define ZLIB			8
55*4887Schin #define MIT			9
56*4887Schin #define GPL			10
57*4887Schin #define SPECIAL			11
58*4887Schin #define NONEXCLUSIVE		12
59*4887Schin #define NONCOMMERCIAL		13
60*4887Schin #define PROPRIETARY		14
61*4887Schin 
62*4887Schin #define AUTHOR			0
63*4887Schin #define CLASS			1
64*4887Schin #define COMPANY			2
65*4887Schin #define CONTRIBUTOR		3
66*4887Schin #define CORPORATION		4
67*4887Schin #define DOMAIN			5
68*4887Schin #define INCORPORATION		6
69*4887Schin #define LICENSE			7
70*4887Schin #define LOCATION		8
71*4887Schin #define NOTICE			9
72*4887Schin #define ORGANIZATION		10
73*4887Schin #define PACKAGE			11
74*4887Schin #define PARENT			12
75*4887Schin #define QUERY			13
76*4887Schin #define SINCE			14
77*4887Schin #define STYLE			15
78*4887Schin #define URL			16
79*4887Schin #define URLMD5			17
80*4887Schin #define VERSION			18
81*4887Schin 
82*4887Schin #define IDS			64
83*4887Schin 
84*4887Schin #define COMDATA			70
85*4887Schin #define COMLINE			(COMDATA+4)
86*4887Schin #define COMLONG			(COMDATA-32)
87*4887Schin #define COMMENT(x,b,s,u)	comment(x,b,s,sizeof(s)-1,u)
88*4887Schin 
89*4887Schin #define PUT(b,c)		(((b)->nxt<(b)->end)?(*(b)->nxt++=(c)):((c),(-1)))
90*4887Schin #define BUF(b)			((b)->buf)
91*4887Schin #define USE(b)			((b)->siz=(b)->nxt-(b)->buf,(b)->nxt=(b)->buf,(b)->siz)
92*4887Schin #define SIZ(b)			((b)->nxt-(b)->buf)
93*4887Schin #define END(b)			(*((b)->nxt>=(b)->end?((b)->nxt=(b)->end-1):(b)->nxt)=0,(b)->nxt-(b)->buf)
94*4887Schin 
95*4887Schin #ifndef NiL
96*4887Schin #define NiL			((char*)0)
97*4887Schin #endif
98*4887Schin 
99*4887Schin typedef struct Buffer_s
100*4887Schin {
101*4887Schin 	char*		buf;
102*4887Schin 	char*		nxt;
103*4887Schin 	char*		end;
104*4887Schin 	int		siz;
105*4887Schin } Buffer_t;
106*4887Schin 
107*4887Schin typedef struct Item_s
108*4887Schin {
109*4887Schin 	char*		data;
110*4887Schin 	int		size;
111*4887Schin 	int		quote;
112*4887Schin } Item_t;
113*4887Schin 
114*4887Schin typedef struct Id_s
115*4887Schin {
116*4887Schin 	Item_t		name;
117*4887Schin 	Item_t		value;
118*4887Schin } Id_t;
119*4887Schin 
120*4887Schin /*
121*4887Schin  * NOTE: key[] element order must match the corresponding macro
122*4887Schin  */
123*4887Schin 
124*4887Schin #define KEY(s)			{s,sizeof(s)-1,0}
125*4887Schin 
126*4887Schin static const Item_t	key[] =
127*4887Schin {
128*4887Schin 	KEY("author"),
129*4887Schin 	KEY("class"),
130*4887Schin 	KEY("company"),
131*4887Schin 	KEY("contributor"),
132*4887Schin 	KEY("corporation"),
133*4887Schin 	KEY("domain"),
134*4887Schin 	KEY("incorporation"),
135*4887Schin 	KEY("license"),
136*4887Schin 	KEY("location"),
137*4887Schin 	KEY("notice"),
138*4887Schin 	KEY("organization"),
139*4887Schin 	KEY("package"),
140*4887Schin 	KEY("parent"),
141*4887Schin 	KEY("query"),
142*4887Schin 	KEY("since"),
143*4887Schin 	KEY("type"),
144*4887Schin 	KEY("url"),
145*4887Schin 	KEY("urlmd5"),
146*4887Schin 	KEY("version"),
147*4887Schin 	{0}
148*4887Schin };
149*4887Schin 
150*4887Schin #define ITEMS			(sizeof(key)/sizeof(key[0])-1)
151*4887Schin 
152*4887Schin #define LIC(s,c)		{s,sizeof(s)-1,c}
153*4887Schin 
154*4887Schin static const Item_t	lic[] =
155*4887Schin {
156*4887Schin 	LIC("none", NONE),
157*4887Schin 	LIC("inline", SPECIAL),
158*4887Schin 	LIC("test", TEST),
159*4887Schin 	LIC("verbose", VERBOSE),
160*4887Schin 	LIC("usage", USAGE),
161*4887Schin 	LIC("open", OPEN),
162*4887Schin 	LIC("cpl", OPEN),
163*4887Schin 	LIC("bsd", OPEN),
164*4887Schin 	LIC("zlib", OPEN),
165*4887Schin 	LIC("mit", OPEN),
166*4887Schin 	LIC("gpl", GPL),
167*4887Schin 	LIC("special", SPECIAL),
168*4887Schin 	LIC("nonexclusive", SPECIAL),
169*4887Schin 	LIC("noncommercial", SPECIAL),
170*4887Schin 	LIC("proprietary", PROPRIETARY),
171*4887Schin 	{0}
172*4887Schin };
173*4887Schin 
174*4887Schin typedef struct Notice_s
175*4887Schin {
176*4887Schin 	int		test;
177*4887Schin 	int		type;
178*4887Schin 	int		verbose;
179*4887Schin 	int		ids;
180*4887Schin 	Item_t		item[ITEMS];
181*4887Schin 	Id_t		id[IDS];
182*4887Schin 	char		cc[3];
183*4887Schin } Notice_t;
184*4887Schin 
185*4887Schin /*
186*4887Schin  * return index given <name,size>
187*4887Schin  */
188*4887Schin 
189*4887Schin static int
190*4887Schin lookup(register const Item_t* item, const char* name, int size)
191*4887Schin {
192*4887Schin 	register int	c;
193*4887Schin 	register int	i;
194*4887Schin 
195*4887Schin 	c = name[0];
196*4887Schin 	for (i = 0; item[i].data; i++)
197*4887Schin 		if (c == item[i].data[0] && size == item[i].size && !strncmp(name, item[i].data, size))
198*4887Schin 			return i;
199*4887Schin 	return -1;
200*4887Schin }
201*4887Schin 
202*4887Schin /*
203*4887Schin  * copy s of size n to b
204*4887Schin  * n<0 means 0 terminated string
205*4887Schin  */
206*4887Schin 
207*4887Schin static void
208*4887Schin copy(register Buffer_t* b, register char* s, int n)
209*4887Schin {
210*4887Schin 	if (n < 0)
211*4887Schin 		n = strlen(s);
212*4887Schin 	while (n--)
213*4887Schin 		PUT(b, *s++);
214*4887Schin }
215*4887Schin 
216*4887Schin /*
217*4887Schin  * center and copy comment line s to p
218*4887Schin  * if s==0 then
219*4887Schin  *	n>0	first frame line
220*4887Schin  *	n=0	blank line
221*4887Schin  *	n<0	last frame line
222*4887Schin  * if u>0 then s converted to upper case
223*4887Schin  * if u<0 then s is left justified
224*4887Schin  */
225*4887Schin 
226*4887Schin static void
227*4887Schin comment(Notice_t* notice, register Buffer_t* b, register char* s, register int n, int u)
228*4887Schin {
229*4887Schin 	register int	i;
230*4887Schin 	register int	m;
231*4887Schin 	register int	x;
232*4887Schin 	int		cc;
233*4887Schin 
234*4887Schin 	cc = notice->cc[1];
235*4887Schin 	if (!s)
236*4887Schin 	{
237*4887Schin 		if (n)
238*4887Schin 		{
239*4887Schin 			PUT(b, notice->cc[n > 0 ? 0 : 1]);
240*4887Schin 			for (i = 0; i < COMDATA; i++)
241*4887Schin 				PUT(b, cc);
242*4887Schin 			PUT(b, notice->cc[n > 0 ? 1 : 2]);
243*4887Schin 		}
244*4887Schin 		else
245*4887Schin 			s = "";
246*4887Schin 	}
247*4887Schin 	if (s)
248*4887Schin 	{
249*4887Schin 		if (n > COMDATA)
250*4887Schin 			n = COMDATA;
251*4887Schin 		PUT(b, cc);
252*4887Schin 		m = (u < 0) ? 1 : (COMDATA - n) / 2;
253*4887Schin 		if ((x = COMDATA - m - n) < 0)
254*4887Schin 			n--;
255*4887Schin 		while (m-- > 0)
256*4887Schin 			PUT(b, ' ');
257*4887Schin 		while (n-- > 0)
258*4887Schin 		{
259*4887Schin 			i = *s++;
260*4887Schin 			if (u > 0 && i >= 'a' && i <= 'z')
261*4887Schin 				i = i - 'a' + 'A';
262*4887Schin 			PUT(b, i);
263*4887Schin 		}
264*4887Schin 		while (x-- > 0)
265*4887Schin 			PUT(b, ' ');
266*4887Schin 		PUT(b, cc);
267*4887Schin 	}
268*4887Schin 	PUT(b, '\n');
269*4887Schin }
270*4887Schin 
271*4887Schin /*
272*4887Schin  * expand simple ${...}
273*4887Schin  */
274*4887Schin 
275*4887Schin static void
276*4887Schin expand(Notice_t* notice, register Buffer_t* b, const Item_t* item)
277*4887Schin {
278*4887Schin 	register char*	t;
279*4887Schin 	register char*	e;
280*4887Schin 	register int	q;
281*4887Schin 	register char*	x;
282*4887Schin 	register char*	z;
283*4887Schin 	register int	c;
284*4887Schin 
285*4887Schin 	if (t = item->data)
286*4887Schin 	{
287*4887Schin 		q = item->quote;
288*4887Schin 		e = t + item->size;
289*4887Schin 		while (t < e)
290*4887Schin 		{
291*4887Schin 			if (*t == '$' && t < (e + 2) && *(t + 1) == '{')
292*4887Schin 			{
293*4887Schin 				x = t += 2;
294*4887Schin 				while (t < e && (c = *t++) != '}')
295*4887Schin 					if (c == '.')
296*4887Schin 						x = t;
297*4887Schin 				if ((c = lookup(key, x, t - x - 1)) >= 0 && (x = notice->item[c].data))
298*4887Schin 				{
299*4887Schin 					z = x + notice->item[c].size;
300*4887Schin 					while (x < z)
301*4887Schin 						PUT(b, *x++);
302*4887Schin 				}
303*4887Schin 			}
304*4887Schin 			else if (q > 0 && *t == '\\' && (*(t + 1) == q || *(t + 1) == '\\'))
305*4887Schin 				t++;
306*4887Schin 			else
307*4887Schin 				PUT(b, *t++);
308*4887Schin 		}
309*4887Schin 	}
310*4887Schin }
311*4887Schin 
312*4887Schin /*
313*4887Schin  * generate a copright notice
314*4887Schin  */
315*4887Schin 
316*4887Schin static void
317*4887Schin copyright(Notice_t* notice, register Buffer_t* b)
318*4887Schin {
319*4887Schin 	register char*	x;
320*4887Schin 	register char*	t;
321*4887Schin 	time_t		clock;
322*4887Schin 
323*4887Schin 	copy(b, "Copyright (c) ", -1);
324*4887Schin 	if (notice->test)
325*4887Schin 		clock = (time_t)1000212300;
326*4887Schin 	else
327*4887Schin 		time(&clock);
328*4887Schin 	t = ctime(&clock) + 20;
329*4887Schin 	if ((x = notice->item[SINCE].data) && strncmp(x, t, 4))
330*4887Schin 	{
331*4887Schin 		expand(notice, b, &notice->item[SINCE]);
332*4887Schin 		PUT(b, '-');
333*4887Schin 	}
334*4887Schin 	copy(b, t, 4);
335*4887Schin 	if (notice->item[PARENT].data)
336*4887Schin 	{
337*4887Schin 		PUT(b, ' ');
338*4887Schin 		expand(notice, b, &notice->item[PARENT]);
339*4887Schin 	}
340*4887Schin 	if (notice->item[CORPORATION].data)
341*4887Schin 	{
342*4887Schin 		PUT(b, ' ');
343*4887Schin 		expand(notice, b, &notice->item[CORPORATION]);
344*4887Schin 		if (notice->item[INCORPORATION].data)
345*4887Schin 		{
346*4887Schin 			PUT(b, ' ');
347*4887Schin 			expand(notice, b, &notice->item[INCORPORATION]);
348*4887Schin 		}
349*4887Schin 	}
350*4887Schin 	else if (notice->item[COMPANY].data)
351*4887Schin 	{
352*4887Schin 		PUT(b, ' ');
353*4887Schin 		expand(notice, b, &notice->item[COMPANY]);
354*4887Schin 	}
355*4887Schin }
356*4887Schin 
357*4887Schin /*
358*4887Schin  * read the license file and generate a comment in p, length size
359*4887Schin  * license length in p returned, -1 on error
360*4887Schin  * -1 return places 0 terminated error string in p
361*4887Schin  */
362*4887Schin 
363*4887Schin int
364*4887Schin astlicense(char* p, int size, char* file, char* options, int cc1, int cc2, int cc3)
365*4887Schin {
366*4887Schin 	register char*	s;
367*4887Schin 	register char*	v;
368*4887Schin 	register char*	x;
369*4887Schin 	register int	c;
370*4887Schin 	int		i;
371*4887Schin 	int		h;
372*4887Schin 	int		k;
373*4887Schin 	int		n;
374*4887Schin 	int		q;
375*4887Schin 	int		contributor;
376*4887Schin 	int		first;
377*4887Schin 	int		line;
378*4887Schin 	int		quote;
379*4887Schin 	char		tmpbuf[COMLINE];
380*4887Schin 	char		info[8 * 1024];
381*4887Schin 	Notice_t	notice;
382*4887Schin 	Item_t		item;
383*4887Schin 	Buffer_t	buf;
384*4887Schin 	Buffer_t	tmp;
385*4887Schin 
386*4887Schin 	buf.end = (buf.buf = buf.nxt = p) + size;
387*4887Schin 	tmp.end = (tmp.buf = tmp.nxt = tmpbuf) + sizeof(tmpbuf);
388*4887Schin 	if (file && *file)
389*4887Schin 	{
390*4887Schin 		if ((i = open(file, O_RDONLY)) < 0)
391*4887Schin 		{
392*4887Schin 			copy(&buf, file, -1);
393*4887Schin 			copy(&buf, ": cannot open", -1);
394*4887Schin 			PUT(&buf, 0);
395*4887Schin 			return -1;
396*4887Schin 		}
397*4887Schin 		n = read(i, info, sizeof(info) - 1);
398*4887Schin 		close(i);
399*4887Schin 		if (n < 0)
400*4887Schin 		{
401*4887Schin 			copy(&buf, file, -1);
402*4887Schin 			copy(&buf, ": cannot read", -1);
403*4887Schin 			PUT(&buf, 0);
404*4887Schin 			return -1;
405*4887Schin 		}
406*4887Schin 		s = info;
407*4887Schin 		s[n] = 0;
408*4887Schin 	}
409*4887Schin 	else if (!options)
410*4887Schin 		return 0;
411*4887Schin 	else
412*4887Schin 	{
413*4887Schin 		s = options;
414*4887Schin 		options = 0;
415*4887Schin 	}
416*4887Schin 	notice.test = 0;
417*4887Schin 	notice.type = NONE;
418*4887Schin 	notice.verbose = 0;
419*4887Schin 	notice.ids = 0;
420*4887Schin 	notice.cc[0] = cc1;
421*4887Schin 	notice.cc[1] = cc2;
422*4887Schin 	notice.cc[2] = cc3;
423*4887Schin 	for (i = 0; i < ITEMS; i++)
424*4887Schin 		notice.item[i].data = 0;
425*4887Schin 	notice.item[STYLE] = notice.item[CLASS] = lic[notice.type];
426*4887Schin 	notice.item[STYLE].quote = notice.item[CLASS].quote = 0;
427*4887Schin 	contributor = i = k = 0;
428*4887Schin 	line = 0;
429*4887Schin 	for (;;)
430*4887Schin 	{
431*4887Schin 		for (first = 1; c = *s; first = 0)
432*4887Schin 		{
433*4887Schin 			while (c == ' ' || c == '\t' || c == '\n' && ++line || c == '\r' || c == ',' || c == ';' || c == ')')
434*4887Schin 				c = *++s;
435*4887Schin 			if (!c)
436*4887Schin 				break;
437*4887Schin 			if (c == '#')
438*4887Schin 			{
439*4887Schin 				while (*++s && *s != '\n');
440*4887Schin 				if (*s)
441*4887Schin 					s++;
442*4887Schin 				line++;
443*4887Schin 				continue;
444*4887Schin 			}
445*4887Schin 			if (c == '\n')
446*4887Schin 			{
447*4887Schin 				s++;
448*4887Schin 				line++;
449*4887Schin 				continue;
450*4887Schin 			}
451*4887Schin 			if (c == '[')
452*4887Schin 				c = *++s;
453*4887Schin 			x = s;
454*4887Schin 			n = 0;
455*4887Schin 			while (c && c != '=' && c != ']' && c != ')' && c != ',' && c != ' ' && c != '\t' && c != '\n' && c != '\r')
456*4887Schin 				c = *++s;
457*4887Schin 			n = s - x;
458*4887Schin 			h = lookup(key, x, n);
459*4887Schin 			if (c == ']')
460*4887Schin 				c = *++s;
461*4887Schin 			if (c == '=' || first)
462*4887Schin 			{
463*4887Schin 				if (c == '=')
464*4887Schin 				{
465*4887Schin 					q = ((c = *++s) == '"' || c == '\'') ? *s++ : 0;
466*4887Schin 					if (c == '(')
467*4887Schin 					{
468*4887Schin 						s++;
469*4887Schin 						if (h == LICENSE)
470*4887Schin 							contributor = 0;
471*4887Schin 						else if (h == CONTRIBUTOR)
472*4887Schin 							contributor = 1;
473*4887Schin 						else
474*4887Schin 						{
475*4887Schin 							q = 1;
476*4887Schin 							i = 0;
477*4887Schin 							for (;;)
478*4887Schin 							{
479*4887Schin 								switch (*s++)
480*4887Schin 								{
481*4887Schin 								case 0:
482*4887Schin 									s--;
483*4887Schin 									break;
484*4887Schin 								case '(':
485*4887Schin 									if (!i)
486*4887Schin 										q++;
487*4887Schin 									continue;
488*4887Schin 								case ')':
489*4887Schin 									if (!i && !--q)
490*4887Schin 										break;
491*4887Schin 									continue;
492*4887Schin 								case '"':
493*4887Schin 								case '\'':
494*4887Schin 									if (!i)
495*4887Schin 										i = *(s - 1);
496*4887Schin 									else if (i == *(s - 1))
497*4887Schin 										i = 0;
498*4887Schin 									continue;
499*4887Schin 								case '\\':
500*4887Schin 									if (*s == i && i == '"')
501*4887Schin 										i++;
502*4887Schin 									continue;
503*4887Schin 								case '\n':
504*4887Schin 									line++;
505*4887Schin 									continue;
506*4887Schin 								default:
507*4887Schin 									continue;
508*4887Schin 								}
509*4887Schin 								break;
510*4887Schin 							}
511*4887Schin 						}
512*4887Schin 						continue;
513*4887Schin 					}
514*4887Schin 					quote = 0;
515*4887Schin 					v = s;
516*4887Schin 					while ((c = *s) && (q == '"' && (c == '\\' && (*(s + 1) == '"' || *(s + 1) == '\\') && s++ && (quote = q)) || q && c != q || !q && c != ' ' && c != '\t' && c != '\n' && c != '\r' && c != ',' && c != ';'))
517*4887Schin 					{
518*4887Schin 						if (c == '\n')
519*4887Schin 							line++;
520*4887Schin 						s++;
521*4887Schin 					}
522*4887Schin 				}
523*4887Schin 				else
524*4887Schin 				{
525*4887Schin 					h = STYLE;
526*4887Schin 					v = x;
527*4887Schin 				}
528*4887Schin 				if (c == '\n')
529*4887Schin 					line++;
530*4887Schin 				if (contributor)
531*4887Schin 				{
532*4887Schin 					for (i = 0; i < notice.ids; i++)
533*4887Schin 						if (n == notice.id[i].name.size && !strncmp(x, notice.id[i].name.data, n))
534*4887Schin 							break;
535*4887Schin 					if (i < IDS)
536*4887Schin 					{
537*4887Schin 						notice.id[i].name.data = x;
538*4887Schin 						notice.id[i].name.size = n;
539*4887Schin 						notice.id[i].name.quote = 0;
540*4887Schin 						notice.id[i].value.data = v;
541*4887Schin 						notice.id[i].value.size = s - v;
542*4887Schin 						notice.id[i].value.quote = quote;
543*4887Schin 						if (notice.ids <= i)
544*4887Schin 							notice.ids = i + 1;
545*4887Schin 					}
546*4887Schin 				}
547*4887Schin 				else if (h == QUERY)
548*4887Schin 				{
549*4887Schin 					if ((s - v) == 3 && v[0] == 'a' && v[1] == 'l' && v[2] == 'l')
550*4887Schin 					{
551*4887Schin 						for (i = 0; i < ITEMS; i++)
552*4887Schin 							if (notice.item[i].size)
553*4887Schin 							{
554*4887Schin 								expand(&notice, &buf, &key[i]);
555*4887Schin 								PUT(&buf, '=');
556*4887Schin 								for (h = 0;; h++)
557*4887Schin 									if (h >= notice.item[i].size)
558*4887Schin 									{
559*4887Schin 										h = 0;
560*4887Schin 										break;
561*4887Schin 									}
562*4887Schin 									else if (notice.item[i].data[h] == ' ' || notice.item[i].data[h] == '\t')
563*4887Schin 										break;
564*4887Schin 								if (h)
565*4887Schin 									PUT(&buf, '\'');
566*4887Schin 								expand(&notice, &buf, &notice.item[i]);
567*4887Schin 								if (h)
568*4887Schin 									PUT(&buf, '\'');
569*4887Schin 								PUT(&buf, '\n');
570*4887Schin 							}
571*4887Schin 					}
572*4887Schin 					else
573*4887Schin 					{
574*4887Schin 						if ((h = lookup(key, v, s - v)) < 0)
575*4887Schin 						{
576*4887Schin 							item.data = v;
577*4887Schin 							item.size = s - v;
578*4887Schin 							item.quote = 0;
579*4887Schin 							expand(&notice, &buf, &item);
580*4887Schin 						}
581*4887Schin 						else
582*4887Schin 							expand(&notice, &buf, &notice.item[h]);
583*4887Schin 						PUT(&buf, '\n');
584*4887Schin 					}
585*4887Schin 					return END(&buf);
586*4887Schin 				}
587*4887Schin 				else
588*4887Schin 				{
589*4887Schin 					if (h == STYLE)
590*4887Schin 						switch (c = lookup(lic, v, s - v))
591*4887Schin 						{
592*4887Schin 						case NONE:
593*4887Schin 							return 0;
594*4887Schin 						case TEST:
595*4887Schin 							notice.test = 1;
596*4887Schin 							h = -1;
597*4887Schin 							break;
598*4887Schin 						case VERBOSE:
599*4887Schin 							notice.verbose = 1;
600*4887Schin 							h = -1;
601*4887Schin 							break;
602*4887Schin 						case USAGE:
603*4887Schin 							notice.type = c;
604*4887Schin 							h = -1;
605*4887Schin 							break;
606*4887Schin 						case -1:
607*4887Schin 							c = SPECIAL;
608*4887Schin 							/*FALLTHROUGH*/
609*4887Schin 						default:
610*4887Schin 							notice.type = c;
611*4887Schin 							notice.item[CLASS].data = lic[lic[c].quote].data;
612*4887Schin 							notice.item[CLASS].size = lic[lic[c].quote].size;
613*4887Schin 							break;
614*4887Schin 						}
615*4887Schin 					if (h >= 0)
616*4887Schin 					{
617*4887Schin 						notice.item[h].data = (notice.item[h].size = s - v) ? v : (char*)0;
618*4887Schin 						notice.item[h].quote = quote;
619*4887Schin 						k = 1;
620*4887Schin 					}
621*4887Schin 				}
622*4887Schin 			}
623*4887Schin 			else
624*4887Schin 			{
625*4887Schin 				if (file)
626*4887Schin 				{
627*4887Schin 					copy(&buf, "\"", -1);
628*4887Schin 					copy(&buf, file, -1);
629*4887Schin 					copy(&buf, "\", line ", -1);
630*4887Schin 					x = &tmpbuf[sizeof(tmpbuf)];
631*4887Schin 					*--x = 0;
632*4887Schin 					line++;
633*4887Schin 					do *--x = ("0123456789")[line % 10]; while (line /= 10);
634*4887Schin 					copy(&buf, x, -1);
635*4887Schin 					copy(&buf, ": ", -1);
636*4887Schin 				}
637*4887Schin 				copy(&buf, "option error: assignment expected", -1);
638*4887Schin 				PUT(&buf, 0);
639*4887Schin 				return -1;
640*4887Schin 			}
641*4887Schin 			if (*s)
642*4887Schin 				s++;
643*4887Schin 		}
644*4887Schin 		if (!options || !*(s = options))
645*4887Schin 			break;
646*4887Schin 		options = 0;
647*4887Schin 	}
648*4887Schin 	if (!k)
649*4887Schin 		return 0;
650*4887Schin 	if (notice.type == INLINE && (!notice.verbose || !notice.item[NOTICE].data))
651*4887Schin 		return 0;
652*4887Schin 	if (notice.type != USAGE)
653*4887Schin 	{
654*4887Schin 		if (!notice.type)
655*4887Schin 			notice.type = SPECIAL;
656*4887Schin 		comment(&notice, &buf, NiL, 1, 0);
657*4887Schin 		comment(&notice, &buf, NiL, 0, 0);
658*4887Schin 		if (notice.item[PACKAGE].data)
659*4887Schin 		{
660*4887Schin 			copy(&tmp, "This software is part of the ", -1);
661*4887Schin 			expand(&notice, &tmp, &notice.item[PACKAGE]);
662*4887Schin 			copy(&tmp, " package", -1);
663*4887Schin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
664*4887Schin 		}
665*4887Schin 		if (notice.type >= OPEN)
666*4887Schin 		{
667*4887Schin 			copyright(&notice, &tmp);
668*4887Schin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
669*4887Schin 			if (notice.type >= SPECIAL)
670*4887Schin 				COMMENT(&notice, &buf, "All Rights Reserved", 0);
671*4887Schin 		}
672*4887Schin 		if (notice.type == CPL)
673*4887Schin 		{
674*4887Schin 			copy(&tmp, notice.item[PACKAGE].data ? "and" : "This software", -1);
675*4887Schin 			copy(&tmp, " is licensed under the", -1);
676*4887Schin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
677*4887Schin 			copy(&tmp, "Common Public License", -1);
678*4887Schin 			if (notice.item[VERSION].data)
679*4887Schin 			{
680*4887Schin 				copy(&tmp, ", Version ", -1);
681*4887Schin 				expand(&notice, &tmp, &notice.item[VERSION]);
682*4887Schin 			}
683*4887Schin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
684*4887Schin 			if (notice.item[CORPORATION].data || notice.item[COMPANY].data)
685*4887Schin 			{
686*4887Schin 				copy(&tmp, "by ", -1);
687*4887Schin 				if (notice.item[PARENT].data)
688*4887Schin 				{
689*4887Schin 					expand(&notice, &tmp, &notice.item[PARENT]);
690*4887Schin 					copy(&tmp, " ", -1);
691*4887Schin 				}
692*4887Schin 				if (notice.item[CORPORATION].data)
693*4887Schin 				{
694*4887Schin 					expand(&notice, &tmp, &notice.item[CORPORATION]);
695*4887Schin 					if (notice.item[INCORPORATION].data)
696*4887Schin 					{
697*4887Schin 						copy(&tmp, " ", -1);
698*4887Schin 						expand(&notice, &tmp, &notice.item[INCORPORATION]);
699*4887Schin 					}
700*4887Schin 				}
701*4887Schin 				else if (notice.item[COMPANY].data)
702*4887Schin 					expand(&notice, &tmp, &notice.item[COMPANY]);
703*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
704*4887Schin 			}
705*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
706*4887Schin 			COMMENT(&notice, &buf, "A copy of the License is available at", 0);
707*4887Schin 			if (notice.item[URL].data)
708*4887Schin 			{
709*4887Schin 				expand(&notice, &tmp, &notice.item[URL]);
710*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
711*4887Schin 				if (notice.item[URLMD5].data)
712*4887Schin 				{
713*4887Schin 					copy(&tmp, "(with md5 checksum ", -1);
714*4887Schin 					expand(&notice, &tmp, &notice.item[URLMD5]);
715*4887Schin 					copy(&tmp, ")", -1);
716*4887Schin 					comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
717*4887Schin 				}
718*4887Schin 			}
719*4887Schin 			else
720*4887Schin 				COMMENT(&notice, &buf, "http://www.opensource.org/licenses/cpl", 0);
721*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
722*4887Schin 		}
723*4887Schin 		else if (notice.type == OPEN)
724*4887Schin 		{
725*4887Schin 			copy(&tmp, notice.item[PACKAGE].data ? "and it" : "This software", -1);
726*4887Schin 			copy(&tmp, " may only be used by you under license from", -1);
727*4887Schin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
728*4887Schin 			if (notice.item[i = CORPORATION].data)
729*4887Schin 			{
730*4887Schin 				if (notice.item[PARENT].data)
731*4887Schin 				{
732*4887Schin 					expand(&notice, &tmp, &notice.item[i = PARENT]);
733*4887Schin 					copy(&tmp, " ", -1);
734*4887Schin 				}
735*4887Schin 				expand(&notice, &tmp, &notice.item[CORPORATION]);
736*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
737*4887Schin 			}
738*4887Schin 			else if (notice.item[i = COMPANY].data)
739*4887Schin 			{
740*4887Schin 				if (notice.item[PARENT].data)
741*4887Schin 				{
742*4887Schin 					expand(&notice, &tmp, &notice.item[i = PARENT]);
743*4887Schin 					copy(&tmp, " ", -1);
744*4887Schin 				}
745*4887Schin 				expand(&notice, &tmp, &notice.item[COMPANY]);
746*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
747*4887Schin 			}
748*4887Schin 			else
749*4887Schin 				i = -1;
750*4887Schin 			if (notice.item[URL].data)
751*4887Schin 			{
752*4887Schin 				COMMENT(&notice, &buf, "A copy of the Source Code Agreement is available", 0);
753*4887Schin 				copy(&tmp, "at the ", -1);
754*4887Schin 				if (i >= 0)
755*4887Schin 					expand(&notice, &tmp, &notice.item[i]);
756*4887Schin 				copy(&tmp, " Internet web site URL", -1);
757*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
758*4887Schin 				comment(&notice, &buf, NiL, 0, 0);
759*4887Schin 				expand(&notice, &tmp, &notice.item[URL]);
760*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
761*4887Schin 				if (notice.item[URLMD5].data)
762*4887Schin 				{
763*4887Schin 					copy(&tmp, "(with an md5 checksum of ", -1);
764*4887Schin 					expand(&notice, &tmp, &notice.item[URLMD5]);
765*4887Schin 					copy(&tmp, ")", -1);
766*4887Schin 					comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
767*4887Schin 				}
768*4887Schin 				comment(&notice, &buf, NiL, 0, 0);
769*4887Schin 			}
770*4887Schin 			COMMENT(&notice, &buf, "If you have copied or used this software without agreeing", 0);
771*4887Schin 			COMMENT(&notice, &buf, "to the terms of the license you are infringing on", 0);
772*4887Schin 			COMMENT(&notice, &buf, "the license and copyright and are violating", 0);
773*4887Schin 			if (i >= 0)
774*4887Schin 				expand(&notice, &tmp, &notice.item[i]);
775*4887Schin 			copy(&tmp, "'s", -1);
776*4887Schin 			if (n >= COMLONG)
777*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
778*4887Schin 			else
779*4887Schin 				PUT(&tmp, ' ');
780*4887Schin 			copy(&tmp, "intellectual property rights.", -1);
781*4887Schin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
782*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
783*4887Schin 		}
784*4887Schin 		else if (notice.type == GPL)
785*4887Schin 		{
786*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
787*4887Schin 			COMMENT(&notice, &buf, "This is free software; you can redistribute it and/or", 0);
788*4887Schin 			COMMENT(&notice, &buf, "modify it under the terms of the GNU General Public License", 0);
789*4887Schin 			COMMENT(&notice, &buf, "as published by the Free Software Foundation;", 0);
790*4887Schin 			COMMENT(&notice, &buf, "either version 2, or (at your option) any later version.", 0);
791*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
792*4887Schin 			COMMENT(&notice, &buf, "This software is distributed in the hope that it", 0);
793*4887Schin 			COMMENT(&notice, &buf, "will be useful, but WITHOUT ANY WARRANTY;", 0);
794*4887Schin 			COMMENT(&notice, &buf, "without even the implied warranty of MERCHANTABILITY", 0);
795*4887Schin 			COMMENT(&notice, &buf, "or FITNESS FOR A PARTICULAR PURPOSE.", 0);
796*4887Schin 			COMMENT(&notice, &buf, "See the GNU General Public License for more details.", 0);
797*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
798*4887Schin 			COMMENT(&notice, &buf, "You should have received a copy of the", 0);
799*4887Schin 			COMMENT(&notice, &buf, "GNU General Public License", 0);
800*4887Schin 			COMMENT(&notice, &buf, "along with this software (see the file COPYING.)", 0);
801*4887Schin 			COMMENT(&notice, &buf, "If not, a copy is available at", 0);
802*4887Schin 			COMMENT(&notice, &buf, "http://www.gnu.org/copyleft/gpl.html", 0);
803*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
804*4887Schin 		}
805*4887Schin 		else if (notice.type == BSD)
806*4887Schin 		{
807*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
808*4887Schin 			COMMENT(&notice, &buf, "Redistribution and use in source and binary forms, with or", -1);
809*4887Schin 			COMMENT(&notice, &buf, "without modification, are permitted provided that the following", -1);
810*4887Schin 			COMMENT(&notice, &buf, "conditions are met:", -1);
811*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
812*4887Schin 			COMMENT(&notice, &buf, "   1. Redistributions of source code must retain the above", -1);
813*4887Schin 			COMMENT(&notice, &buf, "      copyright notice, this list of conditions and the", -1);
814*4887Schin 			COMMENT(&notice, &buf, "      following disclaimer.", -1);
815*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
816*4887Schin 			COMMENT(&notice, &buf, "   2. Redistributions in binary form must reproduce the above", -1);
817*4887Schin 			COMMENT(&notice, &buf, "      copyright notice, this list of conditions and the", -1);
818*4887Schin 			COMMENT(&notice, &buf, "      following disclaimer in the documentation and/or other", -1);
819*4887Schin 			COMMENT(&notice, &buf, "      materials provided with the distribution.", -1);
820*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
821*4887Schin 			copy(&tmp, "   3. Neither the name of ", -1);
822*4887Schin 			if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data || notice.item[i = COMPANY].data)
823*4887Schin 				expand(&notice, &tmp, &notice.item[i]);
824*4887Schin 			else
825*4887Schin 				copy(&tmp, "the copyright holder", -1);
826*4887Schin 			copy(&tmp, " nor the", -1);
827*4887Schin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), -1);
828*4887Schin 			COMMENT(&notice, &buf, "      names of its contributors may be used to endorse or", -1);
829*4887Schin 			COMMENT(&notice, &buf, "      promote products derived from this software without", -1);
830*4887Schin 			COMMENT(&notice, &buf, "      specific prior written permission.", -1);
831*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
832*4887Schin 			COMMENT(&notice, &buf, "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND", -1);
833*4887Schin 			COMMENT(&notice, &buf, "CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,", -1);
834*4887Schin 			COMMENT(&notice, &buf, "INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF", -1);
835*4887Schin 			COMMENT(&notice, &buf, "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE", -1);
836*4887Schin 			COMMENT(&notice, &buf, "DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS", -1);
837*4887Schin 			COMMENT(&notice, &buf, "BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,", -1);
838*4887Schin 			COMMENT(&notice, &buf, "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED", -1);
839*4887Schin 			COMMENT(&notice, &buf, "TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,", -1);
840*4887Schin 			COMMENT(&notice, &buf, "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON", -1);
841*4887Schin 			COMMENT(&notice, &buf, "ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,", -1);
842*4887Schin 			COMMENT(&notice, &buf, "OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY", -1);
843*4887Schin 			COMMENT(&notice, &buf, "OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE", -1);
844*4887Schin 			COMMENT(&notice, &buf, "POSSIBILITY OF SUCH DAMAGE.", -1);
845*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
846*4887Schin 		}
847*4887Schin 		else if (notice.type == ZLIB)
848*4887Schin 		{
849*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
850*4887Schin 			COMMENT(&notice, &buf, "This software is provided 'as-is', without any express or implied", -1);
851*4887Schin 			COMMENT(&notice, &buf, "warranty. In no event will the authors be held liable for any", -1);
852*4887Schin 			COMMENT(&notice, &buf, "damages arising from the use of this software.", -1);
853*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
854*4887Schin 			COMMENT(&notice, &buf, "Permission is granted to anyone to use this software for any", -1);
855*4887Schin 			COMMENT(&notice, &buf, "purpose, including commercial applications, and to alter it and", -1);
856*4887Schin 			COMMENT(&notice, &buf, "redistribute it freely, subject to the following restrictions:", -1);
857*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
858*4887Schin 			COMMENT(&notice, &buf, " 1. The origin of this software must not be misrepresented;", -1);
859*4887Schin 			COMMENT(&notice, &buf, "    you must not claim that you wrote the original software. If", -1);
860*4887Schin 			COMMENT(&notice, &buf, "    you use this software in a product, an acknowledgment in the", -1);
861*4887Schin 			COMMENT(&notice, &buf, "    product documentation would be appreciated but is not", -1);
862*4887Schin 			COMMENT(&notice, &buf, "    required.", -1);
863*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
864*4887Schin 			COMMENT(&notice, &buf, " 2. Altered source versions must be plainly marked as such,", -1);
865*4887Schin 			COMMENT(&notice, &buf, "    and must not be misrepresented as being the original", -1);
866*4887Schin 			COMMENT(&notice, &buf, "    software.", -1);
867*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
868*4887Schin 			COMMENT(&notice, &buf, " 3. This notice may not be removed or altered from any source", -1);
869*4887Schin 			COMMENT(&notice, &buf, "    distribution.", -1);
870*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
871*4887Schin 		}
872*4887Schin 		else if (notice.type == MIT)
873*4887Schin 		{
874*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
875*4887Schin 			COMMENT(&notice, &buf, "Permission is hereby granted, free of charge, to any person", 0);
876*4887Schin 			COMMENT(&notice, &buf, "obtaining a copy of this software and associated", 0);
877*4887Schin 			COMMENT(&notice, &buf, "documentation files (the \"Software\"), to deal in the", 0);
878*4887Schin 			COMMENT(&notice, &buf, "Software without restriction, including without limitation", 0);
879*4887Schin 			COMMENT(&notice, &buf, "the rights to use, copy, modify, merge, publish, distribute,", 0);
880*4887Schin 			COMMENT(&notice, &buf, "sublicense, and/or sell copies of the Software, and to", 0);
881*4887Schin 			COMMENT(&notice, &buf, "permit persons to whom the Software is furnished to do so,", 0);
882*4887Schin 			COMMENT(&notice, &buf, "subject to the following conditions:", 0);
883*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
884*4887Schin 			COMMENT(&notice, &buf, "The above copyright notice and this permission notice shall", 0);
885*4887Schin 			COMMENT(&notice, &buf, "be included in all copies or substantial portions of the", 0);
886*4887Schin 			COMMENT(&notice, &buf, "Software.", 0);
887*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
888*4887Schin 			COMMENT(&notice, &buf, "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY", 0);
889*4887Schin 			COMMENT(&notice, &buf, "KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE", 0);
890*4887Schin 			COMMENT(&notice, &buf, "WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR", 0);
891*4887Schin 			COMMENT(&notice, &buf, "PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS", 0);
892*4887Schin 			COMMENT(&notice, &buf, "OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR", 0);
893*4887Schin 			COMMENT(&notice, &buf, "OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR", 0);
894*4887Schin 			COMMENT(&notice, &buf, "OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE", 0);
895*4887Schin 			COMMENT(&notice, &buf, "SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", 0);
896*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
897*4887Schin 		}
898*4887Schin 		else
899*4887Schin 		{
900*4887Schin 			if (notice.type == PROPRIETARY)
901*4887Schin 			{
902*4887Schin 				if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data || notice.item[i = COMPANY].data)
903*4887Schin 				{
904*4887Schin 					expand(&notice, &tmp, &notice.item[i]);
905*4887Schin 					copy(&tmp, " - ", -1);
906*4887Schin 				}
907*4887Schin 				else
908*4887Schin 					i = -1;
909*4887Schin 				copy(&tmp, "Proprietary", -1);
910*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
911*4887Schin 				comment(&notice, &buf, NiL, 0, 0);
912*4887Schin 				if (notice.item[URL].data)
913*4887Schin 				{
914*4887Schin 					copy(&tmp, "This is proprietary source code", -1);
915*4887Schin 					if (i >= 0)
916*4887Schin 						copy(&tmp, " licensed by", -1);
917*4887Schin 					comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
918*4887Schin 					if (notice.item[PARENT].data)
919*4887Schin 					{
920*4887Schin 						expand(&notice, &tmp, &notice.item[PARENT]);
921*4887Schin 						copy(&tmp, " ", -1);
922*4887Schin 					}
923*4887Schin 					if (notice.item[CORPORATION].data)
924*4887Schin 					{
925*4887Schin 						expand(&notice, &tmp, &notice.item[CORPORATION]);
926*4887Schin 						comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
927*4887Schin 					}
928*4887Schin 					else if (notice.item[COMPANY].data)
929*4887Schin 					{
930*4887Schin 						expand(&notice, &tmp, &notice.item[COMPANY]);
931*4887Schin 						comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
932*4887Schin 					}
933*4887Schin 				}
934*4887Schin 				else
935*4887Schin 				{
936*4887Schin 					copy(&tmp, "This is unpublished proprietary source code", -1);
937*4887Schin 					if (i >= 0)
938*4887Schin 						copy(&tmp, " of", -1);
939*4887Schin 					comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
940*4887Schin 					if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data)
941*4887Schin 						expand(&notice, &tmp, &notice.item[i]);
942*4887Schin 					if (notice.item[COMPANY].data)
943*4887Schin 					{
944*4887Schin 						if (SIZ(&tmp))
945*4887Schin 							PUT(&tmp, ' ');
946*4887Schin 						expand(&notice, &tmp, &notice.item[COMPANY]);
947*4887Schin 					}
948*4887Schin 					if (SIZ(&tmp))
949*4887Schin 						comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
950*4887Schin 					COMMENT(&notice, &buf, "and is not to be disclosed or used except in", 1);
951*4887Schin 					COMMENT(&notice, &buf, "accordance with applicable agreements", 1);
952*4887Schin 				}
953*4887Schin 				comment(&notice, &buf, NiL, 0, 0);
954*4887Schin 			}
955*4887Schin 			else if (notice.type == NONEXCLUSIVE)
956*4887Schin 			{
957*4887Schin 				COMMENT(&notice, &buf, "For nonexclusive individual use", 1);
958*4887Schin 				comment(&notice, &buf, NiL, 0, 0);
959*4887Schin 			}
960*4887Schin 			else if (notice.type == NONCOMMERCIAL)
961*4887Schin 			{
962*4887Schin 				COMMENT(&notice, &buf, "For noncommercial use", 1);
963*4887Schin 				comment(&notice, &buf, NiL, 0, 0);
964*4887Schin 			}
965*4887Schin 			if (notice.type >= PROPRIETARY && !notice.item[URL].data)
966*4887Schin 			{
967*4887Schin 				COMMENT(&notice, &buf, "Unpublished & Not for Publication", 0);
968*4887Schin 				comment(&notice, &buf, NiL, 0, 0);
969*4887Schin 			}
970*4887Schin 			if (notice.item[URL].data)
971*4887Schin 			{
972*4887Schin 				copy(&tmp, "This software is licensed", -1);
973*4887Schin 				if (notice.item[CORPORATION].data || notice.item[COMPANY].data)
974*4887Schin 				{
975*4887Schin 					copy(&tmp, " by", -1);
976*4887Schin 					if ((notice.item[PARENT].size + (notice.item[CORPORATION].data ? (notice.item[CORPORATION].size + notice.item[INCORPORATION].size) : notice.item[COMPANY].size)) >= (COMLONG - 6))
977*4887Schin 						comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
978*4887Schin 					else
979*4887Schin 						PUT(&tmp, ' ');
980*4887Schin 					if (notice.item[PARENT].data)
981*4887Schin 					{
982*4887Schin 						expand(&notice, &tmp, &notice.item[PARENT]);
983*4887Schin 						copy(&tmp, " ", -1);
984*4887Schin 					}
985*4887Schin 					if (notice.item[CORPORATION].data)
986*4887Schin 					{
987*4887Schin 						expand(&notice, &tmp, &notice.item[CORPORATION]);
988*4887Schin 						if (notice.item[INCORPORATION].data)
989*4887Schin 						{
990*4887Schin 							copy(&tmp, " ", -1);
991*4887Schin 							expand(&notice, &tmp, &notice.item[INCORPORATION]);
992*4887Schin 						}
993*4887Schin 					}
994*4887Schin 					else if (notice.item[COMPANY].data)
995*4887Schin 						expand(&notice, &tmp, &notice.item[COMPANY]);
996*4887Schin 				}
997*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
998*4887Schin 				COMMENT(&notice, &buf, "under the terms and conditions of the license in", 0);
999*4887Schin 				expand(&notice, &tmp, &notice.item[URL]);
1000*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1001*4887Schin 				if (notice.item[URLMD5].data)
1002*4887Schin 				{
1003*4887Schin 					copy(&tmp, "(with an md5 checksum of ", -1);
1004*4887Schin 					expand(&notice, &tmp, &notice.item[URLMD5]);
1005*4887Schin 					copy(&tmp, ")", -1);
1006*4887Schin 					comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1007*4887Schin 				}
1008*4887Schin 				comment(&notice, &buf, NiL, 0, 0);
1009*4887Schin 			}
1010*4887Schin 			else if (notice.type == PROPRIETARY)
1011*4887Schin 			{
1012*4887Schin 				COMMENT(&notice, &buf, "The copyright notice above does not evidence any", 0);
1013*4887Schin 				COMMENT(&notice, &buf, "actual or intended publication of such source code", 0);
1014*4887Schin 				comment(&notice, &buf, NiL, 0, 0);
1015*4887Schin 			}
1016*4887Schin 		}
1017*4887Schin 		if (v = notice.item[NOTICE].data)
1018*4887Schin 		{
1019*4887Schin 			x = v + notice.item[NOTICE].size;
1020*4887Schin 			if (*v == '\n')
1021*4887Schin 				v++;
1022*4887Schin 			item.quote = notice.item[NOTICE].quote;
1023*4887Schin 			do
1024*4887Schin 			{
1025*4887Schin 				for (item.data = v; v < x && *v != '\n'; v++);
1026*4887Schin 				if ((item.size = v - item.data) && *item.data == '\t')
1027*4887Schin 				{
1028*4887Schin 					item.data++;
1029*4887Schin 					item.size--;
1030*4887Schin 					h = 0;
1031*4887Schin 				}
1032*4887Schin 				else
1033*4887Schin 					h = -1;
1034*4887Schin 				expand(&notice, &tmp, &item);
1035*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), h);
1036*4887Schin 			} while (v++ < x);
1037*4887Schin 			if (item.size)
1038*4887Schin 				comment(&notice, &buf, NiL, 0, 0);
1039*4887Schin 		}
1040*4887Schin 		if (notice.item[ORGANIZATION].data)
1041*4887Schin 		{
1042*4887Schin 			expand(&notice, &tmp, &notice.item[ORGANIZATION]);
1043*4887Schin 			comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1044*4887Schin 			if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data)
1045*4887Schin 				expand(&notice, &tmp, &notice.item[i]);
1046*4887Schin 			if (notice.item[COMPANY].data)
1047*4887Schin 			{
1048*4887Schin 				if (SIZ(&tmp))
1049*4887Schin 					PUT(&tmp, ' ');
1050*4887Schin 				expand(&notice, &tmp, &notice.item[COMPANY]);
1051*4887Schin 			}
1052*4887Schin 			if (SIZ(&tmp))
1053*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1054*4887Schin 			if (notice.item[LOCATION].data)
1055*4887Schin 			{
1056*4887Schin 				expand(&notice, &tmp, &notice.item[LOCATION]);
1057*4887Schin 				comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1058*4887Schin 			}
1059*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
1060*4887Schin 		}
1061*4887Schin 	}
1062*4887Schin 	if (v = notice.item[AUTHOR].data)
1063*4887Schin 	{
1064*4887Schin 		x = v + notice.item[AUTHOR].size;
1065*4887Schin 		q = (x - v) == 1 && (*v == '*' || *v == '-');
1066*4887Schin 		k = q && notice.type != USAGE ? -1 : 0;
1067*4887Schin 		for (;;)
1068*4887Schin 		{
1069*4887Schin 			if (!q)
1070*4887Schin 			{
1071*4887Schin 				while (v < x && (*v == ' ' || *v == '\t' || *v == '\r' || *v == '\n' || *v == ',' || *v == '+'))
1072*4887Schin 					v++;
1073*4887Schin 				if (v >= x)
1074*4887Schin 					break;
1075*4887Schin 				item.data = v;
1076*4887Schin 				while (v < x && *v != ',' && *v != '+' && *v++ != '>');
1077*4887Schin 				item.size = v - item.data;
1078*4887Schin 				item.quote = notice.item[AUTHOR].quote;
1079*4887Schin 			}
1080*4887Schin 			h = 0;
1081*4887Schin 			for (i = 0; i < notice.ids; i++)
1082*4887Schin 				if (q || item.size == notice.id[i].name.size && !strncmp(item.data, notice.id[i].name.data, item.size))
1083*4887Schin 				{
1084*4887Schin 					h = 1;
1085*4887Schin 					if (notice.type == USAGE)
1086*4887Schin 					{
1087*4887Schin 						copy(&buf, "[-author?", -1);
1088*4887Schin 						expand(&notice, &buf, &notice.id[i].value);
1089*4887Schin 						PUT(&buf, ']');
1090*4887Schin 					}
1091*4887Schin 					else
1092*4887Schin 					{
1093*4887Schin 						if (k < 0)
1094*4887Schin 						{
1095*4887Schin 							COMMENT(&notice, &buf, "CONTRIBUTORS", 0);
1096*4887Schin 							comment(&notice, &buf, NiL, 0, 0);
1097*4887Schin 						}
1098*4887Schin 						k = 1;
1099*4887Schin 						expand(&notice, &tmp, &notice.id[i].value);
1100*4887Schin 						comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1101*4887Schin 					}
1102*4887Schin 					if (!q)
1103*4887Schin 						break;
1104*4887Schin 				}
1105*4887Schin 			if (q)
1106*4887Schin 				break;
1107*4887Schin 			if (!h)
1108*4887Schin 			{
1109*4887Schin 				if (notice.type == USAGE)
1110*4887Schin 				{
1111*4887Schin 					copy(&buf, "[-author?", -1);
1112*4887Schin 					expand(&notice, &buf, &item);
1113*4887Schin 					PUT(&buf, ']');
1114*4887Schin 				}
1115*4887Schin 				else
1116*4887Schin 				{
1117*4887Schin 					if (k < 0)
1118*4887Schin 					{
1119*4887Schin 						COMMENT(&notice, &buf, "CONTRIBUTORS", 0);
1120*4887Schin 						comment(&notice, &buf, NiL, 0, 0);
1121*4887Schin 					}
1122*4887Schin 					k = 1;
1123*4887Schin 					expand(&notice, &tmp, &item);
1124*4887Schin 					comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
1125*4887Schin 				}
1126*4887Schin 			}
1127*4887Schin 		}
1128*4887Schin 		if (k > 0)
1129*4887Schin 			comment(&notice, &buf, NiL, 0, 0);
1130*4887Schin 	}
1131*4887Schin 	if (notice.type == USAGE)
1132*4887Schin 	{
1133*4887Schin 		copy(&buf, "[-copyright?", -1);
1134*4887Schin 		copyright(&notice, &buf);
1135*4887Schin 		PUT(&buf, ']');
1136*4887Schin 		if (notice.item[URL].data)
1137*4887Schin 		{
1138*4887Schin 			copy(&buf, "[-license?", -1);
1139*4887Schin 			expand(&notice, &buf, &notice.item[URL]);
1140*4887Schin 			PUT(&buf, ']');
1141*4887Schin 		}
1142*4887Schin 		PUT(&buf, '\n');
1143*4887Schin 	}
1144*4887Schin 	else
1145*4887Schin 		comment(&notice, &buf, NiL, -1, 0);
1146*4887Schin 	return END(&buf);
1147*4887Schin }
1148