1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1990-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 *                                                                      *
19*b30d1939SAndy Fiddaman ***********************************************************************/
20*b30d1939SAndy Fiddaman #pragma prototyped
21*b30d1939SAndy Fiddaman 
22*b30d1939SAndy Fiddaman /*
23*b30d1939SAndy Fiddaman  * release -- list recent release changes
24*b30d1939SAndy Fiddaman  *
25*b30d1939SAndy Fiddaman  * coded for portability
26*b30d1939SAndy Fiddaman  */
27*b30d1939SAndy Fiddaman 
28*b30d1939SAndy Fiddaman static char id[] = "\n@(#)$Id: release (AT&T Research) 2000-01-28 $\0\n";
29*b30d1939SAndy Fiddaman 
30*b30d1939SAndy Fiddaman #if _PACKAGE_ast
31*b30d1939SAndy Fiddaman 
32*b30d1939SAndy Fiddaman #include <ast.h>
33*b30d1939SAndy Fiddaman #include <error.h>
34*b30d1939SAndy Fiddaman 
35*b30d1939SAndy Fiddaman static const char usage[] =
36*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: release (AT&T Research) 2000-01-28 $\n]"
37*b30d1939SAndy Fiddaman USAGE_LICENSE
38*b30d1939SAndy Fiddaman "[+NAME?release - list recent changes]"
39*b30d1939SAndy Fiddaman "[+DESCRIPTION?\brelease\b lists the changes within the date range specified"
40*b30d1939SAndy Fiddaman "	by the \b--from\b and \b--to\b options. The input files are assumed to"
41*b30d1939SAndy Fiddaman "	contain date tag lines of the form [\acc\a]]\ayy-mm-dd\a [ \atext\a ]]"
42*b30d1939SAndy Fiddaman "	(or \bdate\b(1) default format), where \acc\a is determined by a Y2K"
43*b30d1939SAndy Fiddaman "	window year of 69 (we can produce an example coding dated 1991 - this"
44*b30d1939SAndy Fiddaman "	can be patented?, how about 1+1=2?.) The date tag lines are followed by"
45*b30d1939SAndy Fiddaman "	\areadme\a text in reverse chronological order (newer entries at the"
46*b30d1939SAndy Fiddaman "	top of the file.) If no selection options are spcified then all"
47*b30d1939SAndy Fiddaman "	changes are listed. If no \afile\a operands are specified then the"
48*b30d1939SAndy Fiddaman "	standard input is read.]"
49*b30d1939SAndy Fiddaman "[+?The entries for each \afile\a are annotated with the file directory name.]"
50*b30d1939SAndy Fiddaman "[f:from?Entries older than \adate\a are omitted.]:[date]"
51*b30d1939SAndy Fiddaman "[r:release?List all changes that include the first \acount\a release marks."
52*b30d1939SAndy Fiddaman "	A release mark has a date tag followed by optional space and at least"
53*b30d1939SAndy Fiddaman "	three \b-\b characters. Changes from release mark \acount\a+1 are not"
54*b30d1939SAndy Fiddaman "	listed. If there are no release marks then the date range is used;"
55*b30d1939SAndy Fiddaman "	if there is at least one release mark then the date range is ignored"
56*b30d1939SAndy Fiddaman "	and at most \acount\a release marks will be listed.]#[count]"
57*b30d1939SAndy Fiddaman "[t:to?Entries newer than \adate\a are omitted.]:[date]"
58*b30d1939SAndy Fiddaman "[V?Print the program version and exit.]"
59*b30d1939SAndy Fiddaman 
60*b30d1939SAndy Fiddaman "\n"
61*b30d1939SAndy Fiddaman "\n[ file ... ]\n"
62*b30d1939SAndy Fiddaman "\n"
63*b30d1939SAndy Fiddaman 
64*b30d1939SAndy Fiddaman "[+SEE ALSO?\bpackage\b(1)]"
65*b30d1939SAndy Fiddaman ;
66*b30d1939SAndy Fiddaman 
67*b30d1939SAndy Fiddaman #else
68*b30d1939SAndy Fiddaman 
69*b30d1939SAndy Fiddaman #define elementsof(x)	((int)(sizeof(x)/sizeof(x[0])))
70*b30d1939SAndy Fiddaman 
71*b30d1939SAndy Fiddaman #define NiL		((char*)0)
72*b30d1939SAndy Fiddaman 
73*b30d1939SAndy Fiddaman #endif
74*b30d1939SAndy Fiddaman 
75*b30d1939SAndy Fiddaman #include <stdio.h>
76*b30d1939SAndy Fiddaman #include <unistd.h>
77*b30d1939SAndy Fiddaman #include <ctype.h>
78*b30d1939SAndy Fiddaman #include <sys/types.h>
79*b30d1939SAndy Fiddaman 
80*b30d1939SAndy Fiddaman #if !_PACKAGE_ast && defined(__STDC__)
81*b30d1939SAndy Fiddaman #include <stdlib.h>
82*b30d1939SAndy Fiddaman #include <string.h>
83*b30d1939SAndy Fiddaman #endif
84*b30d1939SAndy Fiddaman 
85*b30d1939SAndy Fiddaman static char	mon[] = "janfebmaraprmayjunjulaugsepoctnovdec";
86*b30d1939SAndy Fiddaman static char	day[] = "sunmontuewedthufrisat";
87*b30d1939SAndy Fiddaman 
88*b30d1939SAndy Fiddaman #if !_PACKAGE_ast
89*b30d1939SAndy Fiddaman 
90*b30d1939SAndy Fiddaman static void
usage()91*b30d1939SAndy Fiddaman usage()
92*b30d1939SAndy Fiddaman {
93*b30d1939SAndy Fiddaman 	fprintf(stderr, "Usage: release [-V] [-h hi-date] [-l lo-date] [-r count] [ file ...]\n");
94*b30d1939SAndy Fiddaman 	exit(2);
95*b30d1939SAndy Fiddaman }
96*b30d1939SAndy Fiddaman 
97*b30d1939SAndy Fiddaman #endif
98*b30d1939SAndy Fiddaman 
99*b30d1939SAndy Fiddaman static unsigned long
number(register char * s,char ** e)100*b30d1939SAndy Fiddaman number(register char* s, char** e)
101*b30d1939SAndy Fiddaman {
102*b30d1939SAndy Fiddaman 	unsigned long	q = 0;
103*b30d1939SAndy Fiddaman 
104*b30d1939SAndy Fiddaman 	while (isspace(*s))
105*b30d1939SAndy Fiddaman 		s++;
106*b30d1939SAndy Fiddaman 	while (isdigit(*s))
107*b30d1939SAndy Fiddaman 		q = q * 10 + *s++ - '0';
108*b30d1939SAndy Fiddaman 	if (e)
109*b30d1939SAndy Fiddaman 		*e = s;
110*b30d1939SAndy Fiddaman 	return q;
111*b30d1939SAndy Fiddaman }
112*b30d1939SAndy Fiddaman 
113*b30d1939SAndy Fiddaman unsigned long
string(register char * s,char * tab,int num,int siz,char ** e)114*b30d1939SAndy Fiddaman string(register char* s, char* tab, int num, int siz, char** e)
115*b30d1939SAndy Fiddaman {
116*b30d1939SAndy Fiddaman 	register int	i;
117*b30d1939SAndy Fiddaman 	register int	j;
118*b30d1939SAndy Fiddaman 	char		buf[16];
119*b30d1939SAndy Fiddaman 
120*b30d1939SAndy Fiddaman 	while (isspace(*s))
121*b30d1939SAndy Fiddaman 		s++;
122*b30d1939SAndy Fiddaman 	for (i = 0; i < siz; i++)
123*b30d1939SAndy Fiddaman 		buf[i] = isupper(s[i]) ? tolower(s[i]) : s[i];
124*b30d1939SAndy Fiddaman 	for (i = 0; i < num; i += siz)
125*b30d1939SAndy Fiddaman 		for (j = 0; j < siz && buf[j] == tab[j+i]; j++)
126*b30d1939SAndy Fiddaman 			if (j == (siz - 1))
127*b30d1939SAndy Fiddaman 			{
128*b30d1939SAndy Fiddaman 				*e = s + siz;
129*b30d1939SAndy Fiddaman 				return i / siz + 1;
130*b30d1939SAndy Fiddaman 			}
131*b30d1939SAndy Fiddaman 	return 0;
132*b30d1939SAndy Fiddaman }
133*b30d1939SAndy Fiddaman 
134*b30d1939SAndy Fiddaman static unsigned long
date(char * s,char ** e)135*b30d1939SAndy Fiddaman date(char* s, char** e)
136*b30d1939SAndy Fiddaman {
137*b30d1939SAndy Fiddaman 	char*		t;
138*b30d1939SAndy Fiddaman 	unsigned long	y;
139*b30d1939SAndy Fiddaman 	unsigned long	m;
140*b30d1939SAndy Fiddaman 	unsigned long	d;
141*b30d1939SAndy Fiddaman 
142*b30d1939SAndy Fiddaman 	if (isdigit(*s))
143*b30d1939SAndy Fiddaman 	{
144*b30d1939SAndy Fiddaman 		y = number(s, &t);
145*b30d1939SAndy Fiddaman 		if (*t != '-')
146*b30d1939SAndy Fiddaman 			return 0;
147*b30d1939SAndy Fiddaman 		switch (t - s)
148*b30d1939SAndy Fiddaman 		{
149*b30d1939SAndy Fiddaman 		case 2:
150*b30d1939SAndy Fiddaman 			y += 1900;
151*b30d1939SAndy Fiddaman 			if (y <= 1969)
152*b30d1939SAndy Fiddaman 				y += 100;
153*b30d1939SAndy Fiddaman 			break;
154*b30d1939SAndy Fiddaman 		case 4:
155*b30d1939SAndy Fiddaman 			if (y < 1969)
156*b30d1939SAndy Fiddaman 				return 0;
157*b30d1939SAndy Fiddaman 			break;
158*b30d1939SAndy Fiddaman 		}
159*b30d1939SAndy Fiddaman 		if (!(m = number(++t, &s)))
160*b30d1939SAndy Fiddaman 			return 0;
161*b30d1939SAndy Fiddaman 		if ((s - t) != 2 || *s != '-' || m < 1 || m > 12)
162*b30d1939SAndy Fiddaman 			return 0;
163*b30d1939SAndy Fiddaman 		if (!(d = number(++s, &t)))
164*b30d1939SAndy Fiddaman 			return 0;
165*b30d1939SAndy Fiddaman 		if ((t - s) != 2 || d < 1 || d > 31)
166*b30d1939SAndy Fiddaman 			return 0;
167*b30d1939SAndy Fiddaman 	}
168*b30d1939SAndy Fiddaman 	else
169*b30d1939SAndy Fiddaman 	{
170*b30d1939SAndy Fiddaman 		if (string(s, day, elementsof(day), 3, &t))
171*b30d1939SAndy Fiddaman 			s = t;
172*b30d1939SAndy Fiddaman 		if (!(m = string(s, mon, elementsof(mon), 3, &t)))
173*b30d1939SAndy Fiddaman 			return 0;
174*b30d1939SAndy Fiddaman 		if (!(d = number(t, &s)))
175*b30d1939SAndy Fiddaman 			return 0;
176*b30d1939SAndy Fiddaman 		for (y = 1969; *s; s++)
177*b30d1939SAndy Fiddaman 			if ((y = number(s, &t)) && (t - s) == 4)
178*b30d1939SAndy Fiddaman 			{
179*b30d1939SAndy Fiddaman 				if (y < 1969)
180*b30d1939SAndy Fiddaman 					return 0;
181*b30d1939SAndy Fiddaman 				break;
182*b30d1939SAndy Fiddaman 			}
183*b30d1939SAndy Fiddaman 	}
184*b30d1939SAndy Fiddaman 	if (e)
185*b30d1939SAndy Fiddaman 	{
186*b30d1939SAndy Fiddaman 		while (isspace(*t))
187*b30d1939SAndy Fiddaman 			t++;
188*b30d1939SAndy Fiddaman 		*e = t;
189*b30d1939SAndy Fiddaman 	}
190*b30d1939SAndy Fiddaman 	return ((y - 1969) * 13 + m) * 32 + d;
191*b30d1939SAndy Fiddaman }
192*b30d1939SAndy Fiddaman 
193*b30d1939SAndy Fiddaman int
main(int argc,char ** argv)194*b30d1939SAndy Fiddaman main(int argc, char** argv)
195*b30d1939SAndy Fiddaman {
196*b30d1939SAndy Fiddaman 	register char*		s;
197*b30d1939SAndy Fiddaman 	register char*		u;
198*b30d1939SAndy Fiddaman 	register char*		v;
199*b30d1939SAndy Fiddaman 	char*			p;
200*b30d1939SAndy Fiddaman 	char*			e;
201*b30d1939SAndy Fiddaman 	int			i;
202*b30d1939SAndy Fiddaman 	unsigned long		t;
203*b30d1939SAndy Fiddaman 	unsigned long		lo;
204*b30d1939SAndy Fiddaman 	unsigned long		hi;
205*b30d1939SAndy Fiddaman 	int			mk;
206*b30d1939SAndy Fiddaman 	FILE*			f;
207*b30d1939SAndy Fiddaman 	char			buf[1024];
208*b30d1939SAndy Fiddaman 
209*b30d1939SAndy Fiddaman 	mk = 0;
210*b30d1939SAndy Fiddaman 	lo = hi = 0;
211*b30d1939SAndy Fiddaman #if _PACKAGE_ast
212*b30d1939SAndy Fiddaman 	error_info.id = "release";
213*b30d1939SAndy Fiddaman 	for (;;)
214*b30d1939SAndy Fiddaman 	{
215*b30d1939SAndy Fiddaman 		switch (optget(argv, usage))
216*b30d1939SAndy Fiddaman 		{
217*b30d1939SAndy Fiddaman 		case 'f':
218*b30d1939SAndy Fiddaman 			if (!(lo = date(opt_info.arg, &e)) || *e)
219*b30d1939SAndy Fiddaman 			{
220*b30d1939SAndy Fiddaman 				error(2, "%s: invalid from date [%s]", opt_info.arg, e);
221*b30d1939SAndy Fiddaman 				return 1;
222*b30d1939SAndy Fiddaman 			}
223*b30d1939SAndy Fiddaman 			continue;
224*b30d1939SAndy Fiddaman 		case 'r':
225*b30d1939SAndy Fiddaman 			mk = opt_info.num + 1;
226*b30d1939SAndy Fiddaman 			continue;
227*b30d1939SAndy Fiddaman 		case 't':
228*b30d1939SAndy Fiddaman 			if (!(hi = date(opt_info.arg, &e)) || *e)
229*b30d1939SAndy Fiddaman 			{
230*b30d1939SAndy Fiddaman 				error(2, "%s: invalid to date [%s]", opt_info.arg, e);
231*b30d1939SAndy Fiddaman 				return 1;
232*b30d1939SAndy Fiddaman 			}
233*b30d1939SAndy Fiddaman 			continue;
234*b30d1939SAndy Fiddaman 		case 'V':
235*b30d1939SAndy Fiddaman 			sfprintf(sfstdout, "%s\n", id + 10);
236*b30d1939SAndy Fiddaman 			return 0;
237*b30d1939SAndy Fiddaman 		case '?':
238*b30d1939SAndy Fiddaman 			error(ERROR_USAGE|4, "%s", opt_info.arg);
239*b30d1939SAndy Fiddaman 			continue;
240*b30d1939SAndy Fiddaman 		case ':':
241*b30d1939SAndy Fiddaman 			error(2, "%s", opt_info.arg);
242*b30d1939SAndy Fiddaman 			continue;
243*b30d1939SAndy Fiddaman 		}
244*b30d1939SAndy Fiddaman 		break;
245*b30d1939SAndy Fiddaman 	}
246*b30d1939SAndy Fiddaman 	if (error_info.errors)
247*b30d1939SAndy Fiddaman 		error(ERROR_USAGE|4, "%s", optusage(NiL));
248*b30d1939SAndy Fiddaman 	argv += opt_info.index;
249*b30d1939SAndy Fiddaman #else
250*b30d1939SAndy Fiddaman 	while ((s = *++argv) && *s == '-' && *(s + 1))
251*b30d1939SAndy Fiddaman 	{
252*b30d1939SAndy Fiddaman 		if (*(s + 1) == '-')
253*b30d1939SAndy Fiddaman 		{
254*b30d1939SAndy Fiddaman 			if (!*(s + 2))
255*b30d1939SAndy Fiddaman 			{
256*b30d1939SAndy Fiddaman 				argv++;
257*b30d1939SAndy Fiddaman 				break;
258*b30d1939SAndy Fiddaman 			}
259*b30d1939SAndy Fiddaman 			usage();
260*b30d1939SAndy Fiddaman 			break;
261*b30d1939SAndy Fiddaman 		}
262*b30d1939SAndy Fiddaman 		for (;;)
263*b30d1939SAndy Fiddaman 		{
264*b30d1939SAndy Fiddaman 			switch (i = *++s)
265*b30d1939SAndy Fiddaman 			{
266*b30d1939SAndy Fiddaman 			case 0:
267*b30d1939SAndy Fiddaman 				break;
268*b30d1939SAndy Fiddaman 			case 'f':
269*b30d1939SAndy Fiddaman 			case 't':
270*b30d1939SAndy Fiddaman 				if (!*(v = ++s) && !(v = *++argv))
271*b30d1939SAndy Fiddaman 				{
272*b30d1939SAndy Fiddaman 					s = "??";
273*b30d1939SAndy Fiddaman 					continue;
274*b30d1939SAndy Fiddaman 				}
275*b30d1939SAndy Fiddaman 				if (!(t = date(v, &e)) || *e)
276*b30d1939SAndy Fiddaman 				{
277*b30d1939SAndy Fiddaman 					fprintf(stderr, "release: -%c%s: invalid date [%s]\n", i, s, e);
278*b30d1939SAndy Fiddaman 					return 1;
279*b30d1939SAndy Fiddaman 				}
280*b30d1939SAndy Fiddaman 				switch (i)
281*b30d1939SAndy Fiddaman 				{
282*b30d1939SAndy Fiddaman 				case 'f':
283*b30d1939SAndy Fiddaman 					lo = t;
284*b30d1939SAndy Fiddaman 					break;
285*b30d1939SAndy Fiddaman 				case 't':
286*b30d1939SAndy Fiddaman 					hi = t;
287*b30d1939SAndy Fiddaman 					break;
288*b30d1939SAndy Fiddaman 				}
289*b30d1939SAndy Fiddaman 				break;
290*b30d1939SAndy Fiddaman 			case 'r':
291*b30d1939SAndy Fiddaman 				if (!*(v = ++s) && !(v = *++argv))
292*b30d1939SAndy Fiddaman 				{
293*b30d1939SAndy Fiddaman 					s = "??";
294*b30d1939SAndy Fiddaman 					continue;
295*b30d1939SAndy Fiddaman 				}
296*b30d1939SAndy Fiddaman 				mk = number(v, &e) + 1;
297*b30d1939SAndy Fiddaman 				if (*e)
298*b30d1939SAndy Fiddaman 				{
299*b30d1939SAndy Fiddaman 					fprintf(stderr, "release: -%c%s: invalid count\n", i, s);
300*b30d1939SAndy Fiddaman 					return 1;
301*b30d1939SAndy Fiddaman 				}
302*b30d1939SAndy Fiddaman 				break;
303*b30d1939SAndy Fiddaman 			case 'V':
304*b30d1939SAndy Fiddaman 				fprintf(stdout, "%s\n", id + 10);
305*b30d1939SAndy Fiddaman 				return 0;
306*b30d1939SAndy Fiddaman 			default:
307*b30d1939SAndy Fiddaman 				fprintf(stderr, "release: -%c: unknown option\n", i);
308*b30d1939SAndy Fiddaman 				/*FALLTHROUGH*/
309*b30d1939SAndy Fiddaman 			case '?':
310*b30d1939SAndy Fiddaman 				usage();
311*b30d1939SAndy Fiddaman 				break;
312*b30d1939SAndy Fiddaman 			}
313*b30d1939SAndy Fiddaman 			break;
314*b30d1939SAndy Fiddaman 		}
315*b30d1939SAndy Fiddaman 	}
316*b30d1939SAndy Fiddaman #endif
317*b30d1939SAndy Fiddaman 	do
318*b30d1939SAndy Fiddaman 	{
319*b30d1939SAndy Fiddaman 		if (!(p = *argv++) || !*p || *p == '-' && !*(p + 1))
320*b30d1939SAndy Fiddaman 		{
321*b30d1939SAndy Fiddaman 			argv--;
322*b30d1939SAndy Fiddaman 			p = "";
323*b30d1939SAndy Fiddaman 			f = stdin;
324*b30d1939SAndy Fiddaman 		}
325*b30d1939SAndy Fiddaman 		else if (!(f = fopen(p, "r")))
326*b30d1939SAndy Fiddaman 		{
327*b30d1939SAndy Fiddaman 			fprintf(stderr, "release: %s: cannot read", p);
328*b30d1939SAndy Fiddaman 			return 1;
329*b30d1939SAndy Fiddaman 		}
330*b30d1939SAndy Fiddaman 		while (s = fgets(buf, sizeof(buf), f))
331*b30d1939SAndy Fiddaman 		{
332*b30d1939SAndy Fiddaman 			if (t = date(s, &e))
333*b30d1939SAndy Fiddaman 			{
334*b30d1939SAndy Fiddaman 				if (mk && e[0] == '-' && e[1] == '-' && e[2] == '-' && !--mk)
335*b30d1939SAndy Fiddaman 					break;
336*b30d1939SAndy Fiddaman 				if (t < lo)
337*b30d1939SAndy Fiddaman 					break;
338*b30d1939SAndy Fiddaman 				if (hi && t > hi)
339*b30d1939SAndy Fiddaman 					continue;
340*b30d1939SAndy Fiddaman 				if (p)
341*b30d1939SAndy Fiddaman 				{
342*b30d1939SAndy Fiddaman 					if (*p)
343*b30d1939SAndy Fiddaman 					{
344*b30d1939SAndy Fiddaman 						for (u = v = p; *p; p++)
345*b30d1939SAndy Fiddaman 							if (*p == '/')
346*b30d1939SAndy Fiddaman 							{
347*b30d1939SAndy Fiddaman 								v = u;
348*b30d1939SAndy Fiddaman 								u = p + 1;
349*b30d1939SAndy Fiddaman 							}
350*b30d1939SAndy Fiddaman 						printf("\n:::::::: ");
351*b30d1939SAndy Fiddaman 						while ((i = *v++) && i != '/')
352*b30d1939SAndy Fiddaman 							fputc(i, stdout);
353*b30d1939SAndy Fiddaman 						printf(" ::::::::\n\n");
354*b30d1939SAndy Fiddaman 					}
355*b30d1939SAndy Fiddaman 					p = 0;
356*b30d1939SAndy Fiddaman 				}
357*b30d1939SAndy Fiddaman 			}
358*b30d1939SAndy Fiddaman 			if (!p)
359*b30d1939SAndy Fiddaman 				fputs(s, stdout);
360*b30d1939SAndy Fiddaman 		}
361*b30d1939SAndy Fiddaman 		if (f == stdin)
362*b30d1939SAndy Fiddaman 			break;
363*b30d1939SAndy Fiddaman 		fclose(f);
364*b30d1939SAndy Fiddaman 	} while (*argv);
365*b30d1939SAndy Fiddaman 	return 0;
366*b30d1939SAndy Fiddaman }
367