|
|
1.1 root 1: /* $Header: intrp.c,v 4.3.1.5 85/05/23 17:21:24 lwall Exp $
2: *
3: * $Log: intrp.c,v $
4: * Revision 4.3.1.5 85/05/23 17:21:24 lwall
5: * Now allows 'r' and 'f' on null articles.
6: *
7: * Revision 4.3.1.4 85/05/21 13:35:21 lwall
8: * Sped up "rn -c" by not doing unnecessary initialization.
9: *
10: * Revision 4.3.1.3 85/05/17 10:37:11 lwall
11: * Fixed & substitution to capitalize last name too.
12: *
13: * Revision 4.3.1.2 85/05/15 14:39:45 lwall
14: * Spelled gecos right.
15: *
16: * Revision 4.3.1.1 85/05/10 11:33:51 lwall
17: * Branch for patches.
18: *
19: * Revision 4.3 85/05/01 11:40:54 lwall
20: * Baseline for release with 4.3bsd.
21: *
22: */
23:
24: #include "EXTERN.h"
25: #include "common.h"
26: #include "util.h"
27: #include "search.h"
28: #include "head.h"
29: #include "rn.h"
30: #include "artsrch.h"
31: #include "ng.h"
32: #include "util.h"
33: #include "respond.h"
34: #include "rcstuff.h"
35: #include "bits.h"
36: #include "artio.h"
37: #include "term.h"
38: #include "final.h"
39: #include "INTERN.h"
40: #include "intrp.h"
41:
42: char orgname[] = ORGNAME;
43:
44: /* name of this site */
45: #ifdef GETHOSTNAME
46: char *hostname;
47: # undef SITENAME
48: # define SITENAME hostname
49: #else !GETHOSTNAME
50: # ifdef DOUNAME
51: # include <sys/utsname.h>
52: struct utsname uts;
53: # undef SITENAME
54: # define SITENAME uts.nodename
55: # else !DOUNAME
56: # ifdef PHOSTNAME
57: char *hostname;
58: # undef SITENAME
59: # define SITENAME hostname
60: # else !PHOSTNAME
61: # ifdef WHOAMI
62: # undef SITENAME
63: # define SITENAME sysname
64: # endif WHOAMI
65: # endif PHOSTNAME
66: # endif DOUNAME
67: #endif GETHOSTNAME
68:
69: #ifdef TILDENAME
70: static char *tildename = Nullch;
71: static char *tildedir = Nullch;
72: #endif
73:
74: char *realname INIT(Nullch); /* real name of sender from /etc/passwd */
75:
76: char *dointerp();
77: char *getrealname();
78: #ifdef CONDSUB
79: char *skipinterp();
80: #endif
81:
82: static void abort_interp();
83:
84: void
85: intrp_init(tcbuf)
86: char *tcbuf;
87: {
88: char *getlogin();
89:
90: spool = savestr(filexp(SPOOL)); /* usually /usr/spool/news */
91:
92: /* get environmental stuff */
93:
94: /* get home directory */
95:
96: homedir = getenv("HOME");
97: if (homedir == Nullch)
98: homedir = getenv("LOGDIR");
99:
100: dotdir = getval("DOTDIR",homedir);
101:
102: /* get login name */
103:
104: logname = getenv("USER");
105: if (logname == Nullch)
106: logname = getenv("LOGNAME");
107: #ifdef GETLOGIN
108: if (logname == Nullch)
109: logname = savestr(getlogin());
110: #endif
111:
112: if (checkflag) /* that getwd below takes ~1/3 sec. */
113: return; /* and we do not need it for -c */
114: getwd(tcbuf); /* find working directory name */
115: origdir = savestr(tcbuf); /* and remember it */
116:
117: /* get the real name of the person (%N) */
118: /* Must be done after logname is read in because BERKNAMES uses that */
119:
120: strcpy(tcbuf,getrealname(getuid()));
121: realname = savestr(tcbuf);
122:
123: /* name of header file (%h) */
124:
125: headname = savestr(filexp(HEADNAME));
126:
127: /* name of this site (%H) */
128:
129: #ifdef GETHOSTNAME
130: gethostname(buf,sizeof buf);
131: hostname = savestr(buf);
132: #else
133: #ifdef DOUNAME
134: /* get sysname */
135: uname(&uts);
136: #else
137: #ifdef PHOSTNAME
138: {
139: FILE *popen();
140: FILE *pipefp = popen(PHOSTNAME,"r");
141:
142: if (pipefp == Nullfp) {
143: printf("Can't find hostname\n");
144: sig_catcher(0);
145: }
146: fgets(buf,sizeof buf,pipefp);
147: buf[strlen(buf)-1] = '\0'; /* wipe out newline */
148: hostname = savestr(buf);
149: pclose(pipefp);
150: }
151: #endif
152: #endif
153: #endif
154: sitename = savestr(SITENAME);
155: }
156:
157: /* expand filename via %, ~, and $ interpretation */
158: /* returns pointer to static area */
159: /* Note that there is a 1-deep cache of ~name interpretation */
160:
161: char *
162: filexp(s)
163: register char *s;
164: {
165: static char filename[CBUFLEN];
166: char scrbuf[CBUFLEN];
167: register char *d;
168:
169: #ifdef DEBUGGING
170: if (debug & DEB_FILEXP)
171: printf("< %s\n",s) FLUSH;
172: #endif
173: interp(filename, (sizeof filename), s); /* interpret any % escapes */
174: #ifdef DEBUGGING
175: if (debug & DEB_FILEXP)
176: printf("%% %s\n",filename) FLUSH;
177: #endif
178: s = filename;
179: if (*s == '~') { /* does destination start with ~? */
180: if (!*(++s) || *s == '/') {
181: sprintf(scrbuf,"%s%s",homedir,s);
182: /* swap $HOME for it */
183: #ifdef DEBUGGING
184: if (debug & DEB_FILEXP)
185: printf("~ %s\n",scrbuf) FLUSH;
186: #endif
187: strcpy(filename,scrbuf);
188: }
189: else {
190: #ifdef TILDENAME
191: for (d=scrbuf; isalnum(*s); s++,d++)
192: *d = *s;
193: *d = '\0';
194: if (tildedir && strEQ(tildename,scrbuf)) {
195: strcpy(scrbuf,tildedir);
196: strcat(scrbuf, s);
197: strcpy(filename, scrbuf);
198: #ifdef DEBUGGING
199: if (debug & DEB_FILEXP)
200: printf("r %s %s\n",tildename,tildedir) FLUSH;
201: #endif
202: }
203: else {
204: if (tildename) {
205: free(tildename);
206: free(tildedir);
207: }
208: tildedir = Nullch;
209: tildename = savestr(scrbuf);
210: #ifdef GETPWENT /* getpwnam() is not the paragon of efficiency */
211: {
212: struct passwd *getpwnam();
213: struct passwd *pwd = getpwnam(tildename);
214:
215: sprintf(scrbuf,"%s%s",pwd->pw_dir,s);
216: tildedir = savestr(pwd->pw_dir);
217: #ifdef NEWSADMIN
218: if (strEQ(newsadmin,tildename))
219: newsuid = atoi(pwd->pw_uid);
220: #endif
221: strcpy(filename,scrbuf);
222: #ifdef GETPWENT
223: endpwent();
224: #endif
225: }
226: #else /* this will run faster, and is less D space */
227: { /* just be sure LOGDIRFIELD is correct */
228: FILE *pfp = fopen("/etc/passwd","r");
229: char tmpbuf[512];
230: int i;
231:
232: if (pfp == Nullfp) {
233: printf(cantopen,"passwd") FLUSH;
234: sig_catcher(0);
235: }
236: while (fgets(tmpbuf,512,pfp) != Nullch) {
237: d = cpytill(scrbuf,tmpbuf,':');
238: #ifdef DEBUGGING
239: if (debug & DEB_FILEXP)
240: printf("p %s\n",tmpbuf) FLUSH;
241: #endif
242: if (strEQ(scrbuf,tildename)) {
243: #ifdef NEWSADMIN
244: if (strEQ(newsadmin,tildename))
245: newsuid = atoi(index(d,':')+1);
246: #endif
247: for (i=LOGDIRFIELD-2; i; i--) {
248: if (d)
249: d = index(d+1,':');
250: }
251: if (d) {
252: cpytill(scrbuf,d+1,':');
253: tildedir = savestr(scrbuf);
254: strcat(scrbuf,s);
255: strcpy(filename,scrbuf);
256: }
257: break;
258: }
259: }
260: fclose(pfp);
261: }
262: #endif
263: }
264: #else !TILDENAME
265: #ifdef VERBOSE
266: IF(verbose)
267: fputs("~loginname not implemented.\n",stdout) FLUSH;
268: ELSE
269: #endif
270: #ifdef TERSE
271: fputs("~login not impl.\n",stdout) FLUSH;
272: #endif
273: #endif
274: }
275: }
276: else if (*s == '$') { /* starts with some env variable? */
277: d = scrbuf;
278: *d++ = '%';
279: if (s[1] == '{')
280: strcpy(d,s+2);
281: else {
282: *d++ = '{';
283: for (s++; isalnum(*s); s++) *d++ = *s;
284: /* skip over token */
285: *d++ = '}';
286: strcpy(d,s);
287: }
288: #ifdef DEBUGGING
289: if (debug & DEB_FILEXP)
290: printf("$ %s\n",scrbuf) FLUSH;
291: #endif
292: interp(filename, (sizeof filename), scrbuf);
293: /* this might do some extra '%'s but */
294: /* that is how the Mercedes Benz */
295: }
296: #ifdef DEBUGGING
297: if (debug & DEB_FILEXP)
298: printf("> %s\n",filename) FLUSH;
299: #endif
300: return filename;
301: }
302:
303: #ifdef CONDSUB
304: /* skip interpolations */
305:
306: char *
307: skipinterp(pattern,stoppers)
308: register char *pattern;
309: char *stoppers;
310: {
311:
312: while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
313: #ifdef DEBUGGING
314: if (debug & 8)
315: printf("skipinterp till %s at %s\n",stoppers?stoppers:"",pattern);
316: #endif
317: if (*pattern == '%' && pattern[1]) {
318: switch (*++pattern) {
319: case '{':
320: for (pattern++; *pattern && *pattern != '}'; pattern++)
321: if (*pattern == '\\')
322: pattern++;
323: break;
324: case '[':
325: for (pattern++; *pattern && *pattern != ']'; pattern++)
326: if (*pattern == '\\')
327: pattern++;
328: break;
329: #ifdef CONDSUB
330: case '(': {
331: pattern = skipinterp(pattern+1,"!=");
332: if (!*pattern)
333: goto getout;
334: for (pattern++; *pattern && *pattern != '?'; pattern++)
335: if (*pattern == '\\')
336: pattern++;
337: if (!*pattern)
338: goto getout;
339: pattern = skipinterp(pattern+1,":)");
340: if (*pattern == ':')
341: pattern = skipinterp(pattern+1,")");
342: break;
343: }
344: #endif
345: #ifdef BACKTICK
346: case '`': {
347: pattern = skipinterp(pattern+1,"`");
348: break;
349: }
350: #endif
351: #ifdef PROMPTTTY
352: case '"':
353: pattern = skipinterp(pattern+1,"\"");
354: break;
355: #endif
356: default:
357: break;
358: }
359: pattern++;
360: }
361: else {
362: if (*pattern == '^' && pattern[1])
363: pattern += 2;
364: else if (*pattern == '\\' && pattern[1])
365: pattern += 2;
366: else
367: pattern++;
368: }
369: }
370: getout:
371: return pattern; /* where we left off */
372: }
373: #endif
374:
375: /* interpret interpolations */
376:
377: char *
378: dointerp(dest,destsize,pattern,stoppers)
379: register char *dest;
380: register int destsize;
381: register char *pattern;
382: char *stoppers;
383: {
384: char *subj_buf = Nullch;
385: char *ngs_buf = Nullch;
386: char *refs_buf = Nullch;
387: char *artid_buf = Nullch;
388: char *reply_buf = Nullch;
389: char *from_buf = Nullch;
390: char *path_buf = Nullch;
391: char *follow_buf = Nullch;
392: char *dist_buf = Nullch;
393: char *line_buf = Nullch;
394: register char *s, *h;
395: register int i;
396: char scrbuf[512];
397: bool upper = FALSE;
398: bool lastcomp = FALSE;
399: int metabit = 0;
400:
401: while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
402: #ifdef DEBUGGING
403: if (debug & 8)
404: printf("dointerp till %s at %s\n",stoppers?stoppers:"",pattern);
405: #endif
406: if (*pattern == '%' && pattern[1]) {
407: upper = FALSE;
408: lastcomp = FALSE;
409: for (s=Nullch; !s; ) {
410: switch (*++pattern) {
411: case '^':
412: upper = TRUE;
413: break;
414: case '_':
415: lastcomp = TRUE;
416: break;
417: case '/':
418: #ifdef ARTSRCH
419: s = scrbuf;
420: if (!index("/?g",pattern[-2]))
421: *s++ = '/';
422: strcpy(s,lastpat);
423: s += strlen(s);
424: if (pattern[-2] != 'g') {
425: if (index("/?",pattern[-2]))
426: *s++ = pattern[-2];
427: else
428: *s++ = '/';
429: if (art_howmuch == 1)
430: *s++ = 'h';
431: else if (art_howmuch == 2)
432: *s++ = 'a';
433: if (art_doread)
434: *s++ = 'r';
435: }
436: *s = '\0';
437: s = scrbuf;
438: #else
439: s = nullstr;
440: #endif
441: break;
442: case '{':
443: pattern = cpytill(scrbuf,pattern+1,'}');
444: if (s = index(scrbuf,'-'))
445: *s++ = '\0';
446: else
447: s = nullstr;
448: s = getval(scrbuf,s);
449: break;
450: case '[':
451: pattern = cpytill(scrbuf,pattern+1,']');
452: i = set_line_type(scrbuf,scrbuf+strlen(scrbuf));
453: if (line_buf)
454: free(line_buf);
455: s = line_buf = fetchlines(art,i);
456: break;
457: #ifdef CONDSUB
458: case '(': {
459: COMPEX *oldbra_compex = bra_compex;
460: COMPEX cond_compex;
461: char rch;
462: bool matched;
463:
464: init_compex(&cond_compex);
465: pattern = dointerp(dest,destsize,pattern+1,"!=");
466: rch = *pattern;
467: if (rch == '!')
468: pattern++;
469: if (*pattern != '=')
470: goto getout;
471: pattern = cpytill(scrbuf,pattern+1,'?');
472: if (!*pattern)
473: goto getout;
474: if (s = compile(&cond_compex,scrbuf,TRUE,TRUE)) {
475: printf("%s: %s\n",scrbuf,s) FLUSH;
476: pattern += strlen(pattern);
477: goto getout;
478: }
479: matched = (execute(&cond_compex,dest) != Nullch);
480: if (cond_compex.nbra) /* were there brackets? */
481: bra_compex = &cond_compex;
482: if (matched==(rch == '=')) {
483: pattern = dointerp(dest,destsize,pattern+1,":)");
484: if (*pattern == ':')
485: pattern = skipinterp(pattern+1,")");
486: }
487: else {
488: pattern = skipinterp(pattern+1,":)");
489: if (*pattern == ':')
490: pattern++;
491: pattern = dointerp(dest,destsize,pattern,")");
492: }
493: s = dest;
494: bra_compex = oldbra_compex;
495: free_compex(&cond_compex);
496: break;
497: }
498: #endif
499: #ifdef BACKTICK
500: case '`': {
501: FILE *pipefp, *popen();
502:
503: pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"`");
504: pipefp = popen(scrbuf,"r");
505: if (pipefp != Nullfp) {
506: int len;
507:
508: len = fread(scrbuf,sizeof(char),(sizeof scrbuf)-1,
509: pipefp);
510: scrbuf[len] = '\0';
511: pclose(pipefp);
512: }
513: else {
514: printf("\nCan't run %s\n",scrbuf);
515: *scrbuf = '\0';
516: }
517: for (s=scrbuf; *s; s++) {
518: if (*s == '\n') {
519: if (s[1])
520: *s = ' ';
521: else
522: *s = '\0';
523: }
524: }
525: s = scrbuf;
526: break;
527: }
528: #endif
529: #ifdef PROMPTTTY
530: case '"':
531: pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"\"");
532: fputs(scrbuf,stdout) FLUSH;
533: resetty();
534: gets(scrbuf);
535: noecho();
536: crmode();
537: s = scrbuf;
538: break;
539: #endif
540: case '~':
541: s = homedir;
542: break;
543: case '.':
544: s = dotdir;
545: break;
546: case '$':
547: s = scrbuf;
548: sprintf(s,"%d",getpid());
549: break;
550: case '0': case '1': case '2': case '3': case '4':
551: case '5': case '6': case '7': case '8': case '9':
552: #ifdef CONDSUB
553: s = getbracket(bra_compex,*pattern - '0');
554: #else
555: s = nullstr;
556: #endif
557: break;
558: case 'a':
559: s = scrbuf;
560: sprintf(s,"%ld",(long)art);
561: break;
562: case 'A':
563: #ifdef LINKART
564: s = linkartname; /* so Eunice people get right file */
565: #else
566: s = scrbuf;
567: sprintf(s,"%s/%s/%ld",spool,ngdir,(long)art);
568: #endif
569: break;
570: case 'b':
571: s = savedest;
572: break;
573: case 'B':
574: s = scrbuf;
575: sprintf(s,"%ld",(long)savefrom);
576: break;
577: case 'c':
578: s = ngdir;
579: break;
580: case 'C':
581: s = ngname;
582: break;
583: case 'd':
584: s = scrbuf;
585: sprintf(s,"%s/%s",spool,ngdir);
586: break;
587: case 'D':
588: s = dist_buf = fetchlines(art,DIST_LINE);
589: break;
590: case 'f': /* from line */
591: #ifdef ASYNC_PARSE
592: parse_maybe(art);
593: #endif
594: if (htype[REPLY_LINE].ht_minpos >= 0) {
595: /* was there a reply line? */
596: if (!(s=reply_buf))
597: s = reply_buf = fetchlines(art,REPLY_LINE);
598: }
599: else if (!(s = from_buf))
600: s = from_buf = fetchlines(art,FROM_LINE);
601: break;
602: case 'F':
603: #ifdef ASYNC_PARSE
604: parse_maybe(art);
605: #endif
606: if (htype[FOLLOW_LINE].ht_minpos >= 0)
607: /* is there a Followup-To line? */
608: s = follow_buf = fetchlines(art,FOLLOW_LINE);
609: else {
610: int off;
611:
612: s = ngs_buf = fetchlines(art,NGS_LINE);
613: if (h = instr(s,"net.general")) {
614: off = h-s;
615: strncpy(scrbuf,s,off+4);
616: strcpy(scrbuf+off+4,"followup");
617: safecpy(scrbuf+off+12,h+11,sizeof(scrbuf));
618: s = scrbuf;
619: }
620: }
621: break;
622: case 'h': /* header file name */
623: s = headname;
624: break;
625: case 'H': /* host name */
626: s = sitename;
627: break;
628: case 'i':
629: if (!(s=artid_buf))
630: s = artid_buf = fetchlines(art,MESSID_LINE);
631: if (*s && *s != '<') {
632: sprintf(scrbuf,"<%s>",artid_buf);
633: s = scrbuf;
634: }
635: break;
636: case 'I': /* ref article indicator */
637: s = scrbuf;
638: sprintf(scrbuf,"'%s'",indstr);
639: break;
640: case 'l': /* rn library */
641: #ifdef NEWSADMIN
642: s = newsadmin;
643: #else
644: s = "???";
645: #endif
646: break;
647: case 'L': /* login id */
648: s = logname;
649: break;
650: case 'm': /* current mode */
651: s = scrbuf;
652: *s = mode;
653: s[1] = '\0';
654: break;
655: case 'M':
656: #ifdef DELAYMARK
657: sprintf(scrbuf,"%ld",(long)dmcount);
658: s = scrbuf;
659: #else
660: s = nullstr;
661: #endif
662: break;
663: case 'n': /* newsgroups */
664: s = ngs_buf = fetchlines(art,NGS_LINE);
665: break;
666: case 'N': /* full name */
667: s = getval("NAME",realname);
668: break;
669: case 'o': /* organization */
670: s = getval("ORGANIZATION",orgname);
671: #ifdef ORGFILE
672: if (*s == '/') {
673: FILE *ofp = fopen(s,"r");
674:
675: if (ofp) {
676: fgets(scrbuf,sizeof scrbuf,ofp);
677: fclose(ofp);
678: s = scrbuf;
679: s[strlen(s)-1] = '\0';
680: }
681: }
682: #endif
683: break;
684: case 'O':
685: s = origdir;
686: break;
687: case 'p':
688: s = cwd;
689: break;
690: case 'P':
691: s = spool;
692: break;
693: case 'r':
694: #ifdef ASYNC_PARSE
695: parse_maybe(art);
696: #endif
697: if (htype[REFS_LINE].ht_minpos >= 0) {
698: refs_buf = fetchlines(art,REFS_LINE);
699: refscpy(scrbuf,(sizeof scrbuf),refs_buf);
700: }
701: else
702: *scrbuf = '\0';
703: s = rindex(scrbuf,'<');
704: break;
705: case 'R':
706: #ifdef ASYNC_PARSE
707: parse_maybe(art);
708: #endif
709: if (htype[REFS_LINE].ht_minpos >= 0) {
710: refs_buf = fetchlines(art,REFS_LINE);
711: refscpy(scrbuf,(sizeof scrbuf),refs_buf);
712: }
713: else
714: *scrbuf = '\0';
715: if (!artid_buf)
716: artid_buf = fetchlines(art,MESSID_LINE);
717: if (artid_buf[0] == '<')
718: safecat(scrbuf,artid_buf,sizeof(scrbuf));
719: else if (artid_buf[0]) {
720: char tmpbuf[64];
721:
722: sprintf(tmpbuf,"<%s>",artid_buf);
723: safecat(scrbuf,tmpbuf,sizeof(scrbuf));
724: }
725: s = scrbuf;
726: break;
727: case 's':
728: if (!(s=subj_buf))
729: s = subj_buf = fetchsubj(art,TRUE,TRUE);
730: /* get subject handy */
731: while ((*s=='R'||*s=='r')&&(s[1]=='E'||s[1]=='e')&&s[2]==':') {
732: /* skip extra Re: */
733: s += 3;
734: if (*s == ' ')
735: s++;
736: }
737: if (h = instr(s,"- (nf"))
738: *h = '\0';
739: break;
740: case 'S':
741: if (!(s=subj_buf))
742: s = subj_buf = fetchsubj(art,TRUE,TRUE);
743: /* get subject handy */
744: if ((*s=='R'||*s=='r')&&(s[1]=='E'||s[1]=='e')&&s[2]==':') {
745: /* skip extra Re: */
746: s += 3;
747: if (*s == ' ')
748: s++;
749: }
750: break;
751: case 't':
752: case 'T':
753: #ifdef ASYNC_PARSE
754: parse_maybe(art);
755: #endif
756: if (htype[REPLY_LINE].ht_minpos >= 0) {
757: /* was there a reply line? */
758: if (!(s=reply_buf))
759: s = reply_buf = fetchlines(art,REPLY_LINE);
760: }
761: else if (!(s = from_buf))
762: s = from_buf = fetchlines(art,FROM_LINE);
763: if (*pattern == 'T') {
764: if (htype[PATH_LINE].ht_minpos >= 0) {
765: /* should we substitute path? */
766: s = path_buf = fetchlines(art,PATH_LINE);
767: }
768: i = strlen(sitename);
769: if (strnEQ(sitename,s,i) && s[i] == '!')
770: s += i + 1;
771: }
772: if ((h=index(s,'(')) != Nullch)
773: /* strip garbage from end */
774: *(h-1) = '\0';
775: else if ((h=index(s,'<')) != Nullch) {
776: /* or perhaps from beginning */
777: s = h+1;
778: if ((h=index(s,'>')) != Nullch)
779: *h = '\0';
780: }
781: break;
782: case 'u':
783: sprintf(scrbuf,"%ld",(long)toread[ng]);
784: s = scrbuf;
785: break;
786: case 'U':
787: sprintf(scrbuf,"%ld",
788: (long)(((ART_NUM)toread[ng]) - 1 + was_read(art)));
789: s = scrbuf;
790: break;
791: case 'x': /* news library */
792: s = lib;
793: break;
794: case 'X': /* rn library */
795: s = rnlib;
796: break;
797: case 'z':
798: #ifdef LINKART
799: s = linkartname; /* so Eunice people get right file */
800: #else
801: s = scrbuf;
802: sprintf(s,"%ld",(long)art);
803: #endif
804: if (stat(s,&filestat) < 0)
805: filestat.st_size = 0L;
806: sprintf(scrbuf,"%5ld",(long)filestat.st_size);
807: s = scrbuf;
808: break;
809: default:
810: if (--destsize <= 0)
811: abort_interp();
812: *dest++ = *pattern | metabit;
813: s = nullstr;
814: break;
815: }
816: }
817: if (!s)
818: s = nullstr;
819: pattern++;
820: if (upper || lastcomp) {
821: char *t;
822:
823: if (s != scrbuf) {
824: safecpy(scrbuf,s,(sizeof scrbuf));
825: s = scrbuf;
826: }
827: if (upper || !(t=rindex(s,'/')))
828: t = s;
829: while (*t && !isalpha(*t))
830: t++;
831: if (islower(*t))
832: *t = toupper(*t);
833: }
834: i = metabit; /* maybe get into register */
835: if (s == dest) {
836: while (*dest) {
837: if (--destsize <= 0)
838: abort_interp();
839: *dest++ |= i;
840: }
841: }
842: else {
843: while (*s) {
844: if (--destsize <= 0)
845: abort_interp();
846: *dest++ = *s++ | i;
847: }
848: }
849: }
850: else {
851: if (--destsize <= 0)
852: abort_interp();
853: if (*pattern == '^' && pattern[1]) {
854: ++pattern; /* skip uparrow */
855: i = *pattern; /* get char into a register */
856: if (i == '?')
857: *dest++ = '\177' | metabit;
858: else if (i == '(') {
859: metabit = 0200;
860: destsize++;
861: }
862: else if (i == ')') {
863: metabit = 0;
864: destsize++;
865: }
866: else
867: *dest++ = i & 037 | metabit;
868: pattern++;
869: }
870: else if (*pattern == '\\' && pattern[1]) {
871: ++pattern; /* skip backslash */
872: i = *pattern; /* get char into a register */
873:
874: /* this used to be a switch but the if may save space */
875:
876: if (i >= '0' && i <= '7') {
877: i = 1;
878: while (i < 01000 && *pattern >= '0' && *pattern <= '7') {
879: i <<= 3;
880: i += *pattern++ - '0';
881: }
882: *dest++ = i & 0377 | metabit;
883: --pattern;
884: }
885: else if (i == 'b')
886: *dest++ = '\b' | metabit;
887: else if (i == 'f')
888: *dest++ = '\f' | metabit;
889: else if (i == 'n')
890: *dest++ = '\n' | metabit;
891: else if (i == 'r')
892: *dest++ = '\r' | metabit;
893: else if (i == 't')
894: *dest++ = '\t' | metabit;
895: else
896: *dest++ = i | metabit;
897: pattern++;
898: }
899: else
900: *dest++ = *pattern++ | metabit;
901: }
902: }
903: *dest = '\0';
904: getout:
905: if (subj_buf != Nullch) /* return any checked out storage */
906: free(subj_buf);
907: if (ngs_buf != Nullch)
908: free(ngs_buf);
909: if (refs_buf != Nullch)
910: free(refs_buf);
911: if (artid_buf != Nullch)
912: free(artid_buf);
913: if (reply_buf != Nullch)
914: free(reply_buf);
915: if (from_buf != Nullch)
916: free(from_buf);
917: if (path_buf != Nullch)
918: free(path_buf);
919: if (follow_buf != Nullch)
920: free(follow_buf);
921: if (dist_buf != Nullch)
922: free(dist_buf);
923: if (line_buf != Nullch)
924: free(line_buf);
925: return pattern; /* where we left off */
926: }
927:
928: void
929: interp(dest,destsize,pattern)
930: char *dest;
931: int destsize;
932: char *pattern;
933: {
934: dointerp(dest,destsize,pattern,Nullch);
935: #ifdef DEBUGGING
936: if (debug & DEB_FILEXP)
937: fputs(dest,stdout);
938: #endif
939: }
940:
941: /* copy a references line, normalizing as we go */
942:
943: void
944: refscpy(dest,destsize,src)
945: register char *dest, *src;
946: register int destsize;
947: {
948: register char *dot, *at, *beg;
949: char tmpbuf[64];
950:
951: while (*src) {
952: if (*src != '<') {
953: if (--destsize <= 0)
954: break;
955: *dest++ = '<';
956: at = dot = Nullch;
957: beg = src;
958: while (*src && *src != ' ' && *src != ',') {
959: if (*src == '.')
960: dot = src;
961: else if (*src == '@')
962: at = src;
963: if (--destsize <= 0)
964: break;
965: *dest++ = *src++;
966: }
967: if (destsize <= 0)
968: break;
969: if (dot && !at) {
970: int len;
971:
972: *dest = *dot++ = '\0';
973: sprintf(tmpbuf,"%s@%s.UUCP",dot,beg);
974: len = strlen(tmpbuf);
975: if (destsize > len) {
976: strcpy(dest,tmpbuf);
977: dest = dest + len;
978: destsize -= len;
979: }
980: }
981: if (--destsize <= 0)
982: break;
983: *dest++ = '>';
984: }
985: else {
986: while (*src && --destsize > 0 && (*dest++ = *src++) != '>') ;
987: if (destsize <= 0)
988: break;
989: }
990: while (*src == ' ' || *src == ',') src++;
991: if (*src && --destsize > 0)
992: *dest++ = ' ';
993: }
994: *dest = '\0';
995: }
996:
997: /* get the person's real name from /etc/passwd */
998: /* (string is overwritten, so it must be copied) */
999:
1000: char *
1001: getrealname(uid)
1002: int uid;
1003: {
1004: char *s, *c;
1005:
1006: #ifdef PASSNAMES
1007: #ifdef GETPWENT
1008: struct passwd *pwd = getpwuid(uid);
1009:
1010: s = pwd->pw_gecos;
1011: #else
1012: char tmpbuf[512];
1013: int i;
1014:
1015: getpw(uid, tmpbuf);
1016: for (s=tmpbuf, i=GCOSFIELD-1; i; i--) {
1017: if (s)
1018: s = index(s,':')+1;
1019: }
1020: if (!s)
1021: return nullstr;
1022: cpytill(tmpbuf,s,':');
1023: s = tmpbuf;
1024: #endif
1025: #ifdef BERKNAMES
1026: #ifdef BERKJUNK
1027: while (*s && !isalnum(*s) && *s != '&') s++;
1028: #endif
1029: if ((c = index(s, ',')) != Nullch)
1030: *c = '\0';
1031: if ((c = index(s, ';')) != Nullch)
1032: *c = '\0';
1033: s = cpytill(buf,s,'&');
1034: if (*s == '&') { /* whoever thought this one up was */
1035: c = buf + strlen(buf); /* in the middle of the night */
1036: strcat(c,logname); /* before the morning after */
1037: strcat(c,s+1);
1038: if (islower(*c))
1039: *c = toupper(*c); /* gack and double gack */
1040: }
1041: #else
1042: if ((c = index(s, '(')) != Nullch)
1043: *c = '\0';
1044: if ((c = index(s, '-')) != Nullch)
1045: s = c;
1046: strcpy(buf,tmpbuf);
1047: #endif
1048: #ifdef GETPWENT
1049: endpwent();
1050: #endif
1051: return buf; /* return something static */
1052: #else
1053: if ((tmpfp=fopen(filexp(FULLNAMEFILE),"r")) != Nullfp) {
1054: fgets(buf,sizeof buf,tmpfp);
1055: fclose(tmpfp);
1056: buf[strlen(buf)-1] = '\0';
1057: return buf;
1058: }
1059: return "PUT YOUR NAME HERE";
1060: #endif
1061: }
1062:
1063: static void
1064: abort_interp()
1065: {
1066: fputs("\n% interp buffer overflow!\n",stdout) FLUSH;
1067: sig_catcher(0);
1068: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.