1*30167Sbostic #ifndef lint
2*30167Sbostic static char sccsid[] = "@(#)unixtomh.c 5.1 86/11/25";
3*30167Sbostic #endif not lint
4*30167Sbostic
5*30167Sbostic /*
6*30167Sbostic * This program copies the mail file in standard unix format
7*30167Sbostic * given as $1 to the file $2 in Rand Message Handler format.
8*30167Sbostic * The change made is to bracket each message with a line
9*30167Sbostic * containing 4 control-A's and to split the From line into
10*30167Sbostic * a From: field and a Date: field, with the date in Arpanet
11*30167Sbostic * standard format.
12*30167Sbostic *
13*30167Sbostic * This program is designed to be called from the rand mh program
14*30167Sbostic * ``inc''
15*30167Sbostic *
16*30167Sbostic * Set SENDMAIL if you are running sendmail -- this guarantees that
17*30167Sbostic * From: and Date: lines will appear already, and will put the info
18*30167Sbostic * in the UNIX-From line into a Received-From: field.
19*30167Sbostic */
20*30167Sbostic
21*30167Sbostic #include <stdio.h>
22*30167Sbostic #include <sys/types.h>
23*30167Sbostic #include <sys/timeb.h>
24*30167Sbostic #include <ctype.h>
25*30167Sbostic
26*30167Sbostic #define SENDMAIL
27*30167Sbostic
28*30167Sbostic struct headline {
29*30167Sbostic char *l_from; /* The name of the sender */
30*30167Sbostic char *l_tty; /* His tty string (if any) */
31*30167Sbostic char *l_date; /* The entire date string */
32*30167Sbostic };
33*30167Sbostic
34*30167Sbostic char *savestr(), *copyin(), *copy(), *nextword(), *calloc();
35*30167Sbostic char *index();
36*30167Sbostic
37*30167Sbostic #define NOSTR ((char *) 0)
38*30167Sbostic #define UUCP /* Undo strange uucp naming */
39*30167Sbostic
main(argc,argv)40*30167Sbostic main(argc, argv)
41*30167Sbostic char **argv;
42*30167Sbostic {
43*30167Sbostic char linebuf[BUFSIZ];
44*30167Sbostic register int maybe;
45*30167Sbostic register FILE *inf, *outf;
46*30167Sbostic int inhdr, infld;
47*30167Sbostic
48*30167Sbostic if (argc > 3) {
49*30167Sbostic fprintf(stderr, "Usage: unixtomh name1 name2\n");
50*30167Sbostic exit(1);
51*30167Sbostic }
52*30167Sbostic outf = inf = NULL;
53*30167Sbostic if (argc < 3)
54*30167Sbostic outf = stdout;
55*30167Sbostic if (argc < 2)
56*30167Sbostic inf = stdin;
57*30167Sbostic if (inf == NULL && (inf = fopen(argv[1], "r")) == NULL) {
58*30167Sbostic perror(argv[1]);
59*30167Sbostic exit(1);
60*30167Sbostic }
61*30167Sbostic if (outf == NULL && (outf = fopen(argv[2], "w")) == NULL) {
62*30167Sbostic perror(argv[2]);
63*30167Sbostic exit(1);
64*30167Sbostic }
65*30167Sbostic maybe = 1;
66*30167Sbostic inhdr = 0;
67*30167Sbostic infld = 0;
68*30167Sbostic while (nullgets(linebuf, BUFSIZ, inf) > 0) {
69*30167Sbostic if (maybe && ishead(linebuf)) {
70*30167Sbostic fputs("\1\1\1\1\n", outf);
71*30167Sbostic inhdr++;
72*30167Sbostic dohead(linebuf, inf, outf);
73*30167Sbostic continue;
74*30167Sbostic }
75*30167Sbostic if (strlen(linebuf) == 0) {
76*30167Sbostic maybe = 1;
77*30167Sbostic inhdr = 0;
78*30167Sbostic infld = 0;
79*30167Sbostic putc('\n', outf);
80*30167Sbostic continue;
81*30167Sbostic }
82*30167Sbostic else
83*30167Sbostic maybe = 0;
84*30167Sbostic #ifndef SENDMAIL
85*30167Sbostic if (inhdr && strcmpn(linebuf, "Date: ", 6) == 0)
86*30167Sbostic continue;
87*30167Sbostic if (inhdr && strcmpn(linebuf, "From: ", 6) == 0)
88*30167Sbostic continue;
89*30167Sbostic #endif SENDMAIL
90*30167Sbostic if (infld && isspace(linebuf[0])) {
91*30167Sbostic fputs(linebuf, outf);
92*30167Sbostic putc('\n', outf);
93*30167Sbostic continue;
94*30167Sbostic }
95*30167Sbostic if (inhdr && !isspace(linebuf[0])) {
96*30167Sbostic char *colp, *sp;
97*30167Sbostic
98*30167Sbostic colp = index(linebuf, ':');
99*30167Sbostic sp = index(linebuf, ' ');
100*30167Sbostic if (colp == NOSTR || sp == NOSTR || sp < colp) {
101*30167Sbostic putc('\n', outf);
102*30167Sbostic inhdr = 0;
103*30167Sbostic }
104*30167Sbostic else
105*30167Sbostic infld = 1;
106*30167Sbostic }
107*30167Sbostic fputs(linebuf, outf);
108*30167Sbostic putc('\n', outf);
109*30167Sbostic }
110*30167Sbostic fputs("\1\1\1\1\n", outf);
111*30167Sbostic fflush(outf);
112*30167Sbostic if (ferror(outf)) {
113*30167Sbostic fprintf(stderr, "unixtomh: write: ");
114*30167Sbostic perror(argv[2]);
115*30167Sbostic exit(1);
116*30167Sbostic }
117*30167Sbostic exit(0);
118*30167Sbostic }
119*30167Sbostic
120*30167Sbostic /*
121*30167Sbostic * Get a line from the given file descriptor, don't return the
122*30167Sbostic * terminating newline.
123*30167Sbostic */
124*30167Sbostic
nullgets(linebuf,sz,file)125*30167Sbostic nullgets(linebuf, sz, file)
126*30167Sbostic char linebuf[];
127*30167Sbostic register FILE *file;
128*30167Sbostic {
129*30167Sbostic register char *cp;
130*30167Sbostic register int c, cnt;
131*30167Sbostic
132*30167Sbostic cp = linebuf;
133*30167Sbostic cnt = sz;
134*30167Sbostic do {
135*30167Sbostic if (--cnt <= 0) {
136*30167Sbostic *cp = 0;
137*30167Sbostic return(1);
138*30167Sbostic }
139*30167Sbostic c = getc(file);
140*30167Sbostic *cp++ = c;
141*30167Sbostic } while (c != EOF && c != '\n');
142*30167Sbostic if (c == EOF && cp == linebuf+1)
143*30167Sbostic return(0);
144*30167Sbostic *--cp = 0;
145*30167Sbostic return(1);
146*30167Sbostic }
147*30167Sbostic
148*30167Sbostic /*
149*30167Sbostic * Output the fields extracted from the From line --
150*30167Sbostic * From: and Date: Untangle UUCP stuff if appropriate.
151*30167Sbostic */
152*30167Sbostic
dohead(line,infile,outfile)153*30167Sbostic dohead(line, infile, outfile)
154*30167Sbostic char line[];
155*30167Sbostic register FILE *infile, *outfile;
156*30167Sbostic {
157*30167Sbostic register char *cp;
158*30167Sbostic struct headline hl;
159*30167Sbostic char parbuf[BUFSIZ];
160*30167Sbostic #ifdef UUCP
161*30167Sbostic char *word();
162*30167Sbostic char namebuf[BUFSIZ];
163*30167Sbostic char linebuf[BUFSIZ];
164*30167Sbostic int first;
165*30167Sbostic long curoff;
166*30167Sbostic #endif UUCP
167*30167Sbostic
168*30167Sbostic parse(line, &hl, parbuf);
169*30167Sbostic #ifndef SENDMAIL
170*30167Sbostic putdate(hl.l_date, outfile);
171*30167Sbostic #endif SENDMAIL
172*30167Sbostic #ifdef UUCP
173*30167Sbostic if (strcmp(hl.l_from, "uucp") == 0) {
174*30167Sbostic strcpy(namebuf, "");
175*30167Sbostic first = 1;
176*30167Sbostic for (;;) {
177*30167Sbostic curoff = ftell(infile);
178*30167Sbostic if (fgets(linebuf, BUFSIZ, infile) == NULL)
179*30167Sbostic break;
180*30167Sbostic if (strcmp(word(1, linebuf), ">From") != 0)
181*30167Sbostic break;
182*30167Sbostic if (strcmp(word(-3, linebuf), "remote") != 0)
183*30167Sbostic break;
184*30167Sbostic if (strcmp(word(-2, linebuf), "from") != 0)
185*30167Sbostic break;
186*30167Sbostic if (first) {
187*30167Sbostic strcpy(namebuf, word(-1, linebuf));
188*30167Sbostic strcat(namebuf, "!");
189*30167Sbostic strcat(namebuf, word(2, linebuf));
190*30167Sbostic first = 0;
191*30167Sbostic }
192*30167Sbostic else {
193*30167Sbostic strcpy(rindex(namebuf, '!')+1,
194*30167Sbostic word(-1, linebuf));
195*30167Sbostic strcat(namebuf, "!");
196*30167Sbostic strcat(namebuf, word(2, linebuf));
197*30167Sbostic }
198*30167Sbostic }
199*30167Sbostic fseek(infile, curoff, 0);
200*30167Sbostic #ifdef SENDMAIL
201*30167Sbostic if (!first)
202*30167Sbostic fprintf(outfile, "Return-Path: <%s>\n", namebuf);
203*30167Sbostic #else SENDMAIL
204*30167Sbostic if (first)
205*30167Sbostic fprintf(outfile, "From: uucp\n");
206*30167Sbostic else
207*30167Sbostic fprintf(outfile, "From: %s\n", namebuf);
208*30167Sbostic #endif SENDMAIL
209*30167Sbostic return;
210*30167Sbostic }
211*30167Sbostic #endif UUCP
212*30167Sbostic #ifdef SENDMAIL
213*30167Sbostic if (hl.l_from[0] == '<')
214*30167Sbostic fprintf(outfile, "Return-Path: %s\n", hl.l_from);
215*30167Sbostic else
216*30167Sbostic fprintf(outfile, "Return-Path: <%s>\n", hl.l_from);
217*30167Sbostic #else SENDMAIL
218*30167Sbostic fprintf(outfile, "From: %s\n", hl.l_from);
219*30167Sbostic #endif SENDMAIL
220*30167Sbostic }
221*30167Sbostic
222*30167Sbostic #ifdef UUCP
223*30167Sbostic
224*30167Sbostic /*
225*30167Sbostic * Return liberal word i from the given string.
226*30167Sbostic * The words are numbered 1, 2, 3, . . . from the left
227*30167Sbostic * and -1, -2, . . . from the right.
228*30167Sbostic */
229*30167Sbostic
230*30167Sbostic char *
word(index,str)231*30167Sbostic word(index, str)
232*30167Sbostic char str[];
233*30167Sbostic {
234*30167Sbostic register char *cp;
235*30167Sbostic char *secbuf;
236*30167Sbostic register int c;
237*30167Sbostic static char retbuf[100];
238*30167Sbostic char *gword();
239*30167Sbostic
240*30167Sbostic cp = str;
241*30167Sbostic if ((c = index) > 0) {
242*30167Sbostic while (c-- > 0)
243*30167Sbostic cp = gword(cp, retbuf);
244*30167Sbostic return(retbuf);
245*30167Sbostic }
246*30167Sbostic if (c == 0)
247*30167Sbostic return("");
248*30167Sbostic secbuf = (char *) alloca(strlen(str) + 1);
249*30167Sbostic strcpy(secbuf, str);
250*30167Sbostic rev(secbuf);
251*30167Sbostic cp = word(-index, secbuf);
252*30167Sbostic rev(cp);
253*30167Sbostic return(cp);
254*30167Sbostic }
255*30167Sbostic
256*30167Sbostic /*
257*30167Sbostic * Skip leading blanks in the string, return
258*30167Sbostic * first liberal word collected.
259*30167Sbostic */
260*30167Sbostic
261*30167Sbostic char *
gword(cp,buf)262*30167Sbostic gword(cp, buf)
263*30167Sbostic register char *cp;
264*30167Sbostic char buf[];
265*30167Sbostic {
266*30167Sbostic register char *cp2;
267*30167Sbostic
268*30167Sbostic cp2 = buf;
269*30167Sbostic while (*cp && any(*cp, " \t\n"))
270*30167Sbostic cp++;
271*30167Sbostic while (*cp && !any(*cp, " \t\n"))
272*30167Sbostic *cp2++ = *cp++;
273*30167Sbostic *cp2 = 0;
274*30167Sbostic return(cp);
275*30167Sbostic }
276*30167Sbostic
277*30167Sbostic /*
278*30167Sbostic * Reverse the characters in the string in place
279*30167Sbostic */
280*30167Sbostic
rev(str)281*30167Sbostic rev(str)
282*30167Sbostic char str[];
283*30167Sbostic {
284*30167Sbostic register char *cpl, *cpr;
285*30167Sbostic register int s;
286*30167Sbostic
287*30167Sbostic s = strlen(str);
288*30167Sbostic cpl = str;
289*30167Sbostic cpr = &str[s-1];
290*30167Sbostic while (cpl < cpr) {
291*30167Sbostic s = *cpl;
292*30167Sbostic *cpl++ = *cpr;
293*30167Sbostic *cpr-- = s;
294*30167Sbostic }
295*30167Sbostic }
296*30167Sbostic #endif UUCP
297*30167Sbostic
298*30167Sbostic /*
299*30167Sbostic * Save a string in dynamic space.
300*30167Sbostic * This little goodie is needed for
301*30167Sbostic * a headline detector in head.c
302*30167Sbostic */
303*30167Sbostic
304*30167Sbostic char *
savestr(str)305*30167Sbostic savestr(str)
306*30167Sbostic char str[];
307*30167Sbostic {
308*30167Sbostic register char *top;
309*30167Sbostic
310*30167Sbostic top = calloc(strlen(str) + 1, 1);
311*30167Sbostic if (top == NOSTR) {
312*30167Sbostic fprintf(stderr, "unixtomh: Ran out of memory\n");
313*30167Sbostic exit(1);
314*30167Sbostic }
315*30167Sbostic copy(str, top);
316*30167Sbostic return(top);
317*30167Sbostic }
318*30167Sbostic
319*30167Sbostic /*
320*30167Sbostic * See if the passed line buffer is a mail header.
321*30167Sbostic * Return true if yes. Note the extreme pains to
322*30167Sbostic * accomodate all funny formats.
323*30167Sbostic */
324*30167Sbostic
ishead(linebuf)325*30167Sbostic ishead(linebuf)
326*30167Sbostic char linebuf[];
327*30167Sbostic {
328*30167Sbostic register char *cp;
329*30167Sbostic struct headline hl;
330*30167Sbostic char parbuf[BUFSIZ];
331*30167Sbostic
332*30167Sbostic cp = linebuf;
333*30167Sbostic if (!isname("From ", cp, 5))
334*30167Sbostic return(0);
335*30167Sbostic parse(cp, &hl, parbuf);
336*30167Sbostic if (hl.l_from == NOSTR || hl.l_date == NOSTR) {
337*30167Sbostic fail(linebuf, "No from or date field");
338*30167Sbostic return(0);
339*30167Sbostic }
340*30167Sbostic if (!isdate(hl.l_date)) {
341*30167Sbostic fail(linebuf, "Date field not legal date");
342*30167Sbostic return(0);
343*30167Sbostic }
344*30167Sbostic
345*30167Sbostic /*
346*30167Sbostic * I guess we got it!
347*30167Sbostic */
348*30167Sbostic
349*30167Sbostic return(1);
350*30167Sbostic }
351*30167Sbostic
fail(linebuf,reason)352*30167Sbostic fail(linebuf, reason)
353*30167Sbostic char linebuf[], reason[];
354*30167Sbostic {
355*30167Sbostic return;
356*30167Sbostic }
357*30167Sbostic
358*30167Sbostic /*
359*30167Sbostic * Split a headline into its useful components.
360*30167Sbostic * Copy the line into dynamic string space, then set
361*30167Sbostic * pointers into the copied line in the passed headline
362*30167Sbostic * structure. Actually, it scans.
363*30167Sbostic */
364*30167Sbostic
parse(line,hl,pbuf)365*30167Sbostic parse(line, hl, pbuf)
366*30167Sbostic char line[], pbuf[];
367*30167Sbostic struct headline *hl;
368*30167Sbostic {
369*30167Sbostic register char *cp, *dp;
370*30167Sbostic char *sp;
371*30167Sbostic char word[BUFSIZ];
372*30167Sbostic
373*30167Sbostic hl->l_from = NOSTR;
374*30167Sbostic hl->l_tty = NOSTR;
375*30167Sbostic hl->l_date = NOSTR;
376*30167Sbostic cp = line;
377*30167Sbostic sp = pbuf;
378*30167Sbostic
379*30167Sbostic /*
380*30167Sbostic * Skip the first "word" of the line, which should be "From"
381*30167Sbostic * anyway.
382*30167Sbostic */
383*30167Sbostic
384*30167Sbostic cp = nextword(cp, word);
385*30167Sbostic dp = nextword(cp, word);
386*30167Sbostic if (word[0] != 0)
387*30167Sbostic hl->l_from = copyin(word, &sp);
388*30167Sbostic if (isname(dp, "tty", 3)) {
389*30167Sbostic cp = nextword(dp, word);
390*30167Sbostic hl->l_tty = copyin(word, &sp);
391*30167Sbostic if (cp != NOSTR)
392*30167Sbostic hl->l_date = copyin(cp, &sp);
393*30167Sbostic }
394*30167Sbostic else
395*30167Sbostic if (dp != NOSTR)
396*30167Sbostic hl->l_date = copyin(dp, &sp);
397*30167Sbostic }
398*30167Sbostic
399*30167Sbostic /*
400*30167Sbostic * Copy the string on the left into the string on the right
401*30167Sbostic * and bump the right (reference) string pointer by the length.
402*30167Sbostic * Thus, dynamically allocate space in the right string, copying
403*30167Sbostic * the left string into it.
404*30167Sbostic */
405*30167Sbostic
406*30167Sbostic char *
copyin(src,space)407*30167Sbostic copyin(src, space)
408*30167Sbostic char src[];
409*30167Sbostic char **space;
410*30167Sbostic {
411*30167Sbostic register char *cp, *top;
412*30167Sbostic register int s;
413*30167Sbostic
414*30167Sbostic s = strlen(src);
415*30167Sbostic cp = *space;
416*30167Sbostic top = cp;
417*30167Sbostic strcpy(cp, src);
418*30167Sbostic cp += s + 1;
419*30167Sbostic *space = cp;
420*30167Sbostic return(top);
421*30167Sbostic }
422*30167Sbostic
423*30167Sbostic /*
424*30167Sbostic * See if the two passed strings agree in the first n characters.
425*30167Sbostic * Return true if they do, gnu.
426*30167Sbostic */
427*30167Sbostic
isname(as1,as2,acount)428*30167Sbostic isname(as1, as2, acount)
429*30167Sbostic char *as1, *as2;
430*30167Sbostic {
431*30167Sbostic register char *s1, *s2;
432*30167Sbostic register count;
433*30167Sbostic
434*30167Sbostic s1 = as1;
435*30167Sbostic s2 = as2;
436*30167Sbostic count = acount;
437*30167Sbostic if (count > 0)
438*30167Sbostic do
439*30167Sbostic if (*s1++ != *s2++)
440*30167Sbostic return(0);
441*30167Sbostic while (--count);
442*30167Sbostic return(1);
443*30167Sbostic }
444*30167Sbostic
445*30167Sbostic /*
446*30167Sbostic * Test to see if the passed string is a ctime(3) generated
447*30167Sbostic * date string as documented in the manual. The template
448*30167Sbostic * below is used as the criterion of correctness.
449*30167Sbostic * Also, we check for a possible trailing time zone using
450*30167Sbostic * the auxtype template.
451*30167Sbostic */
452*30167Sbostic
453*30167Sbostic #define L 1 /* A lower case char */
454*30167Sbostic #define S 2 /* A space */
455*30167Sbostic #define D 3 /* A digit */
456*30167Sbostic #define O 4 /* An optional digit or space */
457*30167Sbostic #define C 5 /* A colon */
458*30167Sbostic #define N 6 /* A new line */
459*30167Sbostic #define U 7 /* An upper case char */
460*30167Sbostic
461*30167Sbostic char ctypes[] = {U,L,L,S,U,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,D,D,D,D,0};
462*30167Sbostic char tmztypes[] = {U,L,L,S,U,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,U,U,U,S,D,D,D,D,0};
463*30167Sbostic
isdate(date)464*30167Sbostic isdate(date)
465*30167Sbostic char date[];
466*30167Sbostic {
467*30167Sbostic register char *cp;
468*30167Sbostic
469*30167Sbostic cp = date;
470*30167Sbostic if (cmatch(cp, ctypes))
471*30167Sbostic return(1);
472*30167Sbostic return(cmatch(cp, tmztypes));
473*30167Sbostic }
474*30167Sbostic
475*30167Sbostic /*
476*30167Sbostic * Match the given string against the given template.
477*30167Sbostic * Return 1 if they match, 0 if they don't
478*30167Sbostic */
479*30167Sbostic
cmatch(str,temp)480*30167Sbostic cmatch(str, temp)
481*30167Sbostic char str[], temp[];
482*30167Sbostic {
483*30167Sbostic register char *cp, *tp;
484*30167Sbostic register int c;
485*30167Sbostic
486*30167Sbostic cp = str;
487*30167Sbostic tp = temp;
488*30167Sbostic while (*cp != '\0' && *tp != 0) {
489*30167Sbostic c = *cp++;
490*30167Sbostic switch (*tp++) {
491*30167Sbostic case L:
492*30167Sbostic if (!islower(c))
493*30167Sbostic return(0);
494*30167Sbostic break;
495*30167Sbostic
496*30167Sbostic case S:
497*30167Sbostic if (c != ' ')
498*30167Sbostic return(0);
499*30167Sbostic break;
500*30167Sbostic
501*30167Sbostic case D:
502*30167Sbostic if (!isdigit(c))
503*30167Sbostic return(0);
504*30167Sbostic break;
505*30167Sbostic
506*30167Sbostic case O:
507*30167Sbostic if (c != ' ' && !isdigit(c))
508*30167Sbostic return(0);
509*30167Sbostic break;
510*30167Sbostic
511*30167Sbostic case C:
512*30167Sbostic if (c != ':')
513*30167Sbostic return(0);
514*30167Sbostic break;
515*30167Sbostic
516*30167Sbostic case N:
517*30167Sbostic if (c != '\n')
518*30167Sbostic return(0);
519*30167Sbostic break;
520*30167Sbostic
521*30167Sbostic case U:
522*30167Sbostic if (!isupper(c))
523*30167Sbostic return(0);
524*30167Sbostic break;
525*30167Sbostic }
526*30167Sbostic }
527*30167Sbostic if (*cp != '\0' || *tp != 0)
528*30167Sbostic return(0);
529*30167Sbostic return(1);
530*30167Sbostic }
531*30167Sbostic
532*30167Sbostic /*
533*30167Sbostic * Collect a liberal (space, tab delimited) word into the word buffer
534*30167Sbostic * passed. Also, return a pointer to the next word following that,
535*30167Sbostic * or NOSTR if none follow.
536*30167Sbostic */
537*30167Sbostic
538*30167Sbostic char *
nextword(wp,wbuf)539*30167Sbostic nextword(wp, wbuf)
540*30167Sbostic char wp[], wbuf[];
541*30167Sbostic {
542*30167Sbostic register char *cp, *cp2;
543*30167Sbostic
544*30167Sbostic if ((cp = wp) == NOSTR) {
545*30167Sbostic copy("", wbuf);
546*30167Sbostic return(NOSTR);
547*30167Sbostic }
548*30167Sbostic cp2 = wbuf;
549*30167Sbostic while (!any(*cp, " \t") && *cp != '\0')
550*30167Sbostic if (*cp == '"') {
551*30167Sbostic *cp2++ = *cp++;
552*30167Sbostic while (*cp != '\0' && *cp != '"')
553*30167Sbostic *cp2++ = *cp++;
554*30167Sbostic if (*cp == '"')
555*30167Sbostic *cp2++ = *cp++;
556*30167Sbostic } else
557*30167Sbostic *cp2++ = *cp++;
558*30167Sbostic *cp2 = '\0';
559*30167Sbostic while (any(*cp, " \t"))
560*30167Sbostic cp++;
561*30167Sbostic if (*cp == '\0')
562*30167Sbostic return(NOSTR);
563*30167Sbostic return(cp);
564*30167Sbostic }
565*30167Sbostic
566*30167Sbostic /*
567*30167Sbostic * Copy str1 to str2, return pointer to null in str2.
568*30167Sbostic */
569*30167Sbostic
570*30167Sbostic char *
copy(str1,str2)571*30167Sbostic copy(str1, str2)
572*30167Sbostic char *str1, *str2;
573*30167Sbostic {
574*30167Sbostic register char *s1, *s2;
575*30167Sbostic
576*30167Sbostic s1 = str1;
577*30167Sbostic s2 = str2;
578*30167Sbostic while (*s1)
579*30167Sbostic *s2++ = *s1++;
580*30167Sbostic *s2 = 0;
581*30167Sbostic return(s2);
582*30167Sbostic }
583*30167Sbostic
584*30167Sbostic /*
585*30167Sbostic * Is ch any of the characters in str?
586*30167Sbostic */
587*30167Sbostic
any(ch,str)588*30167Sbostic any(ch, str)
589*30167Sbostic char *str;
590*30167Sbostic {
591*30167Sbostic register char *f;
592*30167Sbostic register c;
593*30167Sbostic
594*30167Sbostic f = str;
595*30167Sbostic c = ch;
596*30167Sbostic while (*f)
597*30167Sbostic if (c == *f++)
598*30167Sbostic return(1);
599*30167Sbostic return(0);
600*30167Sbostic }
601*30167Sbostic
602*30167Sbostic /*
603*30167Sbostic * Convert lower case letters to upper case.
604*30167Sbostic */
605*30167Sbostic
raise(c)606*30167Sbostic raise(c)
607*30167Sbostic register int c;
608*30167Sbostic {
609*30167Sbostic if (c >= 'a' && c <= 'z')
610*30167Sbostic c += 'A' - 'a';
611*30167Sbostic return(c);
612*30167Sbostic }
613