1bac5051cSeric /*************************************************************************/
2bac5051cSeric /* */
3bac5051cSeric /* prs [-d<dataspec>] [-r<sid>] [-c<cutoff>] [-a] */
4bac5051cSeric /* [-y<reverse-cutoff>] file ... */
5bac5051cSeric /* */
6bac5051cSeric /*************************************************************************/
7bac5051cSeric
8bac5051cSeric /*
9bac5051cSeric Program to print parts or all of an SCCS file
10bac5051cSeric in user supplied format.
11bac5051cSeric Arguments to the program may appear in any order
12bac5051cSeric and consist of keyletters, which begin with '-',
13bac5051cSeric and named files.
14bac5051cSeric
15bac5051cSeric If a direcory is given as an argument, each
16bac5051cSeric SCCS file within the directory is processed as if
17bac5051cSeric it had been specifically named. If a name of '-'
18bac5051cSeric is given, the standard input is read for a list
19bac5051cSeric of names of SCCS files to be processed.
20bac5051cSeric Non-SCCS files are ignored.
21bac5051cSeric */
22bac5051cSeric
23bac5051cSeric # include "../hdr/defines.h"
24bac5051cSeric # include "../hdr/had.h"
25*19db951cSbostic # include "pathnames.h"
26bac5051cSeric
27*19db951cSbostic static char Sccsid[] = "@(#)prs.c 4.4 11/11/90";
28bac5051cSeric
29bac5051cSeric char had[26];
30bac5051cSeric char Sid[32];
31bac5051cSeric char Mod[16];
32bac5051cSeric char *Type;
33bac5051cSeric char Deltadate[18];
34bac5051cSeric char *Deltatime;
355b29b8bcSlepreau char tempskel[] = "/tmp/prXXXXXX"; /* used to generate temp file names */
365b29b8bcSlepreau
37bac5051cSeric char untmp[32], uttmp[32], cmtmp[32];
38bac5051cSeric char mrtmp[32], bdtmp[32];
39bac5051cSeric FILE *UNiop;
40bac5051cSeric FILE *UTiop;
41bac5051cSeric FILE *CMiop;
42bac5051cSeric FILE *MRiop;
43bac5051cSeric FILE *BDiop;
44bac5051cSeric char line[BUFSIZ];
45bac5051cSeric int num_files;
46bac5051cSeric long cutoff;
47bac5051cSeric long revcut;
48bac5051cSeric char *dataspec;
49bac5051cSeric char iline[BUFSIZ], xline[BUFSIZ], gline[BUFSIZ];
50bac5051cSeric char *maket();
51bac5051cSeric struct packet gpkt;
52bac5051cSeric struct sid sid;
534a6a95bbSeric struct tm *Dtime;
54bac5051cSeric
main(argc,argv)55bac5051cSeric main(argc,argv)
56bac5051cSeric int argc;
57bac5051cSeric char *argv[];
58bac5051cSeric {
59bac5051cSeric register int j;
60bac5051cSeric register char *p;
61bac5051cSeric char c;
62bac5051cSeric extern prs();
63bac5051cSeric extern int Fcnt;
64bac5051cSeric
65bac5051cSeric /*
66bac5051cSeric Set flags for 'fatal' to issue message, call clean-up
67bac5051cSeric routine, and terminate processing.
68bac5051cSeric */
69bac5051cSeric Fflags = FTLMSG | FTLCLN | FTLEXIT;
70bac5051cSeric
71bac5051cSeric
72bac5051cSeric /*
73bac5051cSeric The following loop processes keyletters and arguments.
74bac5051cSeric Note that these are processed only once for each
75bac5051cSeric invocation of 'main'.
76bac5051cSeric */
77bac5051cSeric for (j = 1; j < argc; j++)
78bac5051cSeric if (argv[j][0] == '-' && (c = argv[j][1])) {
79bac5051cSeric p = &argv[j][2];
80bac5051cSeric switch (c) {
81bac5051cSeric
82bac5051cSeric case 'r': /* delta cutoff */
83bac5051cSeric if (*p) {
84bac5051cSeric if (invalid(p))
85bac5051cSeric fatal("invalid sid (co8)");
86bac5051cSeric sid_ab(p,&sid);
87bac5051cSeric }
88bac5051cSeric break;
89bac5051cSeric
90bac5051cSeric case 'c': /* time cutoff */
91bac5051cSeric if (*p && date_ab(p,&cutoff))
92bac5051cSeric fatal("bad date/time (cm5)");
93bac5051cSeric break;
94bac5051cSeric
95bac5051cSeric case 'y': /* reverse time cutoff */
96bac5051cSeric if (*p && date_ab(p,&revcut))
97bac5051cSeric fatal ("bad date/time (cm5)");
98bac5051cSeric break;
99bac5051cSeric
100bac5051cSeric case 'a':
101bac5051cSeric if (*p)
102bac5051cSeric fatal("value after a arg (cm7)");
103bac5051cSeric break;
104bac5051cSeric case 'd': /* dataspec line */
105bac5051cSeric dataspec = p;
106bac5051cSeric break;
107bac5051cSeric default:
108bac5051cSeric fatal("unknown key letter (cm1)");
109bac5051cSeric }
110bac5051cSeric
111bac5051cSeric if (had[c - 'a']++)
112bac5051cSeric fatal("key letter twice (cm2)");
113bac5051cSeric argv[j] = 0;
114bac5051cSeric }
115bac5051cSeric else
116bac5051cSeric num_files++;
117bac5051cSeric
118bac5051cSeric if (num_files == 0)
119bac5051cSeric fatal("missing file arg (cm3)");
120bac5051cSeric
121bac5051cSeric if (!HADD)
122bac5051cSeric exit(0);
123bac5051cSeric if (HADC && HADY)
124bac5051cSeric fatal("both 'c' and 'y' keyletters specified (prs2)");
125bac5051cSeric
126bac5051cSeric setsig();
127bac5051cSeric
128bac5051cSeric /*
129bac5051cSeric Change flags for 'fatal' so that it will return to this
130bac5051cSeric routine (main) instead of terminating processing.
131bac5051cSeric */
1325b29b8bcSlepreau Fflags &= ~FTLEXIT;
1335b29b8bcSlepreau Fflags |= FTLJMP;
134bac5051cSeric
135bac5051cSeric /*
136bac5051cSeric Call 'prs' routine for each file argument.
137bac5051cSeric */
138bac5051cSeric for (j = 1; j < argc; j++)
139bac5051cSeric if (p = argv[j])
140bac5051cSeric do_file(p,prs);
141bac5051cSeric
142bac5051cSeric exit(Fcnt ? 1 : 0);
143bac5051cSeric }
144bac5051cSeric
145bac5051cSeric
prs(file)146bac5051cSeric prs(file)
147bac5051cSeric register char *file;
148bac5051cSeric {
149bac5051cSeric int n;
150bac5051cSeric extern char had_dir, had_standinp;
151bac5051cSeric
152bac5051cSeric if (setjmp(Fjmp))
153bac5051cSeric return;
154bac5051cSeric sinit(&gpkt,file,1); /* init packet and open SCCS file */
155bac5051cSeric
156bac5051cSeric gpkt.p_reqsid.s_rel = sid.s_rel;
157bac5051cSeric gpkt.p_reqsid.s_lev = sid.s_lev;
158bac5051cSeric gpkt.p_reqsid.s_br = sid.s_br;
159bac5051cSeric gpkt.p_reqsid.s_seq = sid.s_seq;
160bac5051cSeric gpkt.p_cutoff = cutoff;
161bac5051cSeric gpkt.p_reopen = 1;
162bac5051cSeric
163bac5051cSeric /*
164bac5051cSeric read delta table entries checking only for format error
165bac5051cSeric */
166bac5051cSeric deltblchk(&gpkt);
167bac5051cSeric
168bac5051cSeric /*
169bac5051cSeric create auxiliary file for User Name Section
170bac5051cSeric */
171bac5051cSeric
172bac5051cSeric aux_create(UNiop,untmp,EUSERNAM);
173bac5051cSeric
174bac5051cSeric doflags(&gpkt);
175bac5051cSeric
176bac5051cSeric /*
177bac5051cSeric create auxiliary file for the User Text section
178bac5051cSeric */
179bac5051cSeric
180bac5051cSeric aux_create(UTiop,uttmp,EUSERTXT);
181bac5051cSeric
182bac5051cSeric /*
183bac5051cSeric indicate to 'getline' that EOF is okay
184bac5051cSeric */
185bac5051cSeric gpkt.p_chkeof = 1;
186bac5051cSeric
187bac5051cSeric /*
188bac5051cSeric read body of SCCS file and create temp file for it
189bac5051cSeric */
190bac5051cSeric while(read_mod(&gpkt))
191bac5051cSeric ;
192bac5051cSeric
193bac5051cSeric if (num_files > 1 || had_dir || had_standinp)
194bac5051cSeric printf("\n%s:\n",gpkt.p_file);
195bac5051cSeric /*
196bac5051cSeric Here, file has already been re-opened (by 'getline')
197bac5051cSeric */
198bac5051cSeric getline(&gpkt); /* skip over header line */
199bac5051cSeric
200bac5051cSeric /*
201bac5051cSeric call dodeltbl to read delta table entries
202bac5051cSeric */
203bac5051cSeric
204bac5051cSeric dodeltbl(&gpkt);
205bac5051cSeric
206bac5051cSeric clean_up();
207bac5051cSeric
208bac5051cSeric return;
209bac5051cSeric }
210bac5051cSeric
211bac5051cSeric
dodeltbl(pkt)212bac5051cSeric dodeltbl(pkt)
213bac5051cSeric register struct packet *pkt;
214bac5051cSeric {
215bac5051cSeric int n;
216bac5051cSeric struct deltab dt;
217bac5051cSeric struct stats stats;
218bac5051cSeric
219bac5051cSeric /*
220bac5051cSeric Read entire delta table.
221bac5051cSeric */
222bac5051cSeric while (getstats(pkt,&stats)) {
223bac5051cSeric if (getadel(pkt,&dt) != BDELTAB)
224bac5051cSeric fmterr(pkt);
225bac5051cSeric
226bac5051cSeric /*
227bac5051cSeric Read rest of delta entry.
228bac5051cSeric */
229bac5051cSeric while ((n = getline(pkt)) != NULL)
230bac5051cSeric if (pkt->p_line[0] != CTLCHAR)
231bac5051cSeric break;
232bac5051cSeric else {
233bac5051cSeric switch (pkt->p_line[1]) {
234bac5051cSeric case EDELTAB:
235bac5051cSeric scanspec(dataspec,&dt,&stats);
236bac5051cSeric break;
237bac5051cSeric case INCLUDE:
238bac5051cSeric getit(iline,n);
239bac5051cSeric continue;
240bac5051cSeric case EXCLUDE:
241bac5051cSeric getit(xline,n);
242bac5051cSeric continue;
243bac5051cSeric case IGNORE:
244bac5051cSeric getit(gline,n);
245bac5051cSeric continue;
246bac5051cSeric case MRNUM:
247bac5051cSeric case COMMENTS:
248bac5051cSeric continue;
249bac5051cSeric default:
250bac5051cSeric fmterr(pkt);
251bac5051cSeric }
252bac5051cSeric break;
253bac5051cSeric }
254bac5051cSeric if (n == NULL || pkt->p_line[0] != CTLCHAR)
255bac5051cSeric fmterr(pkt);
256bac5051cSeric }
257bac5051cSeric }
258bac5051cSeric
259bac5051cSeric
260bac5051cSeric /*
261bac5051cSeric * The scanspec procedure scans the dataspec searching for ID keywords.
262bac5051cSeric * When a keyword is found the value is replaced and printed on the
263bac5051cSeric * standard output. Any character that is not an ID keyword is printed
264bac5051cSeric * immediately.
265bac5051cSeric */
266bac5051cSeric
2675b29b8bcSlepreau static char Zkeywd[5] = "@(#)";
scanspec(spec,dtp,statp)268bac5051cSeric scanspec(spec,dtp,statp)
269bac5051cSeric char spec[];
270bac5051cSeric struct deltab *dtp;
271bac5051cSeric struct stats *statp;
272bac5051cSeric {
273bac5051cSeric
274bac5051cSeric extern char *Sflags[];
275bac5051cSeric register char *lp;
276bac5051cSeric register char *k;
277bac5051cSeric union {
278bac5051cSeric char str[2];
2794a6a95bbSeric short istr;
280bac5051cSeric } u;
281bac5051cSeric register char c;
282bac5051cSeric
283bac5051cSeric idsetup(&dtp->d_sid,&gpkt,&dtp->d_datetime);
284bac5051cSeric for(lp = spec; *lp != 0; lp++) {
285bac5051cSeric if(lp[0] == ':' && lp[1] != 0 && lp[2] == ':') {
286bac5051cSeric c = *++lp;
287bac5051cSeric switch (c) {
288bac5051cSeric case 'I': /* SID */
289bac5051cSeric printf("%s",Sid);
290bac5051cSeric break;
291bac5051cSeric case 'R': /* Release number */
292bac5051cSeric printf("%u",dtp->d_sid.s_rel);
293bac5051cSeric break;
294bac5051cSeric case 'L': /* Level number */
295bac5051cSeric printf("%u",dtp->d_sid.s_lev);
296bac5051cSeric break;
297bac5051cSeric case 'B': /* Branch number */
298bac5051cSeric if (dtp->d_sid.s_br != 0)
299bac5051cSeric printf("%u",dtp->d_sid.s_br);
300bac5051cSeric break;
301bac5051cSeric case 'S': /* Sequence number */
302bac5051cSeric if (dtp->d_sid.s_seq != 0)
303bac5051cSeric printf("%u",dtp->d_sid.s_seq);
304bac5051cSeric break;
305bac5051cSeric case 'D': /* Date delta created */
306bac5051cSeric printf("%s",Deltadate);
307bac5051cSeric break;
308bac5051cSeric case 'T': /* Time delta created */
309bac5051cSeric printf("%s",Deltatime);
310bac5051cSeric break;
311bac5051cSeric case 'P': /* Programmer who created delta */
312bac5051cSeric printf("%s",dtp->d_pgmr);
313bac5051cSeric break;
314bac5051cSeric case 'C': /* Comments */
315bac5051cSeric break;
316bac5051cSeric case 'Y': /* Type flag */
317bac5051cSeric printf("%s",Type);
318bac5051cSeric break;
319bac5051cSeric case 'M': /* Module name */
320bac5051cSeric printf("%s",Mod);
321bac5051cSeric break;
322bac5051cSeric case 'W': /* Form of what string */
323bac5051cSeric printf("%s",Zkeywd);
324bac5051cSeric printf("%s",Mod);
325bac5051cSeric putchar('\t');
326bac5051cSeric printf("%s",Sid);
327bac5051cSeric break;
328bac5051cSeric case 'A': /* Form of what string */
329bac5051cSeric printf("%s",Zkeywd);
330bac5051cSeric printf("%s ",Type);
331bac5051cSeric printf("%s ",Mod);
332bac5051cSeric printf("%s",Sid);
333bac5051cSeric printf("%s",Zkeywd);
334bac5051cSeric break;
335bac5051cSeric case 'Z': /* what string constructor */
336bac5051cSeric printf("%s",Zkeywd);
337bac5051cSeric break;
338bac5051cSeric case 'F': /* File name */
339bac5051cSeric printf("%s",sname(gpkt.p_file));
340bac5051cSeric break;
341bac5051cSeric default:
342bac5051cSeric putchar(':');
343bac5051cSeric putchar(c);
344bac5051cSeric putchar(':');
345bac5051cSeric break;
346bac5051cSeric }
347bac5051cSeric lp++;
348bac5051cSeric }
349bac5051cSeric else if(lp[0] == ':' && lp[1] != 0 && lp[2] !=0 && lp[3] == ':') {
350bac5051cSeric if (lp[1] == ':') {
351bac5051cSeric putchar(':');
3525b29b8bcSlepreau *lp += 2;
353bac5051cSeric continue;
354bac5051cSeric }
355bac5051cSeric u.str[1] = *++lp;
3564a6a95bbSeric u.str[0] = *++lp;
357bac5051cSeric switch (u.istr) {
358bac5051cSeric case 'Dl': /* Delta line statistics */
359bac5051cSeric printf("%05d",statp->s_ins);
360bac5051cSeric putchar('/');
361bac5051cSeric printf("%05d",statp->s_del);
362bac5051cSeric putchar('/');
363bac5051cSeric printf("%05d",statp->s_unc);
364bac5051cSeric break;
365bac5051cSeric case 'Li': /* Lines inserted by delta */
366bac5051cSeric printf("%05d",statp->s_ins);
367bac5051cSeric break;
368bac5051cSeric case 'Ld': /* Lines deleted by delta */
369bac5051cSeric printf("%05d",statp->s_del);
370bac5051cSeric break;
371bac5051cSeric case 'Lu': /* Lines unchanged by delta */
372bac5051cSeric printf("%05d",statp->s_unc);
373bac5051cSeric break;
374bac5051cSeric case 'DT': /* Delta type */
375bac5051cSeric printf("%c",dtp->d_type);
376bac5051cSeric break;
377bac5051cSeric case 'Dy': /* Year delta created */
3784a6a95bbSeric printf("%02d",Dtime->tm_year);
379bac5051cSeric break;
380bac5051cSeric case 'Dm': /* Month delta created */
3814a6a95bbSeric printf("%02d",(Dtime->tm_mon + 1));
382bac5051cSeric break;
383bac5051cSeric case 'Dd': /* Day delta created */
3844a6a95bbSeric printf("%02d",Dtime->tm_mday);
385bac5051cSeric break;
386bac5051cSeric case 'Th': /* Hour delta created */
3874a6a95bbSeric printf("%02d",Dtime->tm_hour);
388bac5051cSeric break;
389bac5051cSeric case 'Tm': /* Minutes delta created */
3904a6a95bbSeric printf("%02d",Dtime->tm_min);
391bac5051cSeric break;
392bac5051cSeric case 'Ts': /* Seconds delta created */
3934a6a95bbSeric printf("%02d",Dtime->tm_sec);
394bac5051cSeric break;
395bac5051cSeric case 'DS': /* Delta sequence number */
396bac5051cSeric printf("%d",dtp->d_serial);
397bac5051cSeric break;
398bac5051cSeric case 'DP': /* Predecessor delta sequence number */
399bac5051cSeric printf("%d",dtp->d_pred);
400bac5051cSeric break;
401bac5051cSeric case 'DI': /* Deltas included,excluded,ignored */
402bac5051cSeric printf("%s",iline);
403bac5051cSeric putchar('/');
404bac5051cSeric printf("%s",xline);
405bac5051cSeric putchar('/');
406bac5051cSeric printf("%s",gline);
407bac5051cSeric break;
408bac5051cSeric case 'Di': /* Deltas included */
409bac5051cSeric printf("%s",iline);
410bac5051cSeric break;
411bac5051cSeric case 'Dx': /* Deltas excluded */
412bac5051cSeric printf("%s",xline);
413bac5051cSeric break;
414bac5051cSeric case 'Dg': /* Deltas ignored */
415bac5051cSeric printf("%s",gline);
416bac5051cSeric break;
417bac5051cSeric case 'MR': /* MR numbers */
418bac5051cSeric break;
419bac5051cSeric case 'UN': /* User names */
420bac5051cSeric printfile(untmp);
421bac5051cSeric break;
422bac5051cSeric case 'MF': /* MR validation flag */
423bac5051cSeric if (Sflags[VALFLAG - 'a'])
424bac5051cSeric printf("yes");
425bac5051cSeric else printf("no");
426bac5051cSeric break;
427bac5051cSeric case 'MP': /* MR validation program */
428bac5051cSeric if (!(k = Sflags[VALFLAG - 'a']))
429bac5051cSeric printf("none");
430bac5051cSeric else printf("%s",k);
431bac5051cSeric break;
432bac5051cSeric case 'KF': /* Keyword err/warn flag */
433bac5051cSeric if (Sflags[IDFLAG - 'a'])
434bac5051cSeric printf("yes");
435bac5051cSeric else printf("no");
436bac5051cSeric break;
437bac5051cSeric case 'BF': /* Branch flag */
438bac5051cSeric if (Sflags[BRCHFLAG - 'a'])
439bac5051cSeric printf("yes");
440bac5051cSeric else printf("no");
441bac5051cSeric break;
442bac5051cSeric case 'FB': /* Floor Boundry */
443bac5051cSeric if (k = Sflags[FLORFLAG - 'a'])
444bac5051cSeric printf("%s",k);
445bac5051cSeric else printf("none");
446bac5051cSeric break;
447bac5051cSeric case 'CB': /* Ceiling Boundry */
448bac5051cSeric if (k = Sflags[CEILFLAG - 'a'])
449bac5051cSeric printf("%s",k);
450bac5051cSeric else printf("none");
451bac5051cSeric break;
452bac5051cSeric case 'Ds': /* Default SID */
453bac5051cSeric if (k = Sflags[DEFTFLAG - 'a'])
454bac5051cSeric printf("%s",k);
455bac5051cSeric else printf("none");
456bac5051cSeric break;
457bac5051cSeric case 'ND': /* Null delta */
458bac5051cSeric if (Sflags[NULLFLAG - 'a'])
459bac5051cSeric printf("yes");
460bac5051cSeric else printf("no");
461bac5051cSeric break;
462bac5051cSeric case 'FD': /* File descriptive text */
463bac5051cSeric printfile(uttmp);
464bac5051cSeric break;
465bac5051cSeric case 'BD': /* Entire file body */
466bac5051cSeric printfile(bdtmp);
467bac5051cSeric break;
468bac5051cSeric case 'GB': /* Gotten body from 'get' */
469bac5051cSeric getbody(&dtp->d_sid,&gpkt);
470bac5051cSeric break;
471bac5051cSeric default:
472bac5051cSeric putchar(':');
473bac5051cSeric printf("%c",u.istr);
474bac5051cSeric putchar(':');
475bac5051cSeric break;
476bac5051cSeric }
477bac5051cSeric lp++;
478bac5051cSeric }
479bac5051cSeric else {
480bac5051cSeric c = *lp;
481bac5051cSeric if (c == '\\') {
482bac5051cSeric switch(*++lp) {
483bac5051cSeric case 'n': /* for newline */
484bac5051cSeric putchar('\n');
485bac5051cSeric break;
486bac5051cSeric case ':': /* for wanted colon */
487bac5051cSeric putchar(':');
488bac5051cSeric break;
489bac5051cSeric case 't': /* for tab */
490bac5051cSeric putchar('\t');
491bac5051cSeric break;
492bac5051cSeric case 'b': /* for backspace */
493bac5051cSeric putchar('\b');
494bac5051cSeric break;
495bac5051cSeric case 'r': /* for carriage return */
496bac5051cSeric putchar('\r');
497bac5051cSeric break;
498bac5051cSeric case 'f': /* for form feed */
499bac5051cSeric putchar('\f');
500bac5051cSeric break;
501bac5051cSeric case '\\': /* for backslash */
502bac5051cSeric putchar('\\');
503bac5051cSeric break;
504bac5051cSeric case '\'': /* for single quote */
505bac5051cSeric putchar('\'');
506bac5051cSeric break;
507bac5051cSeric default: /* unknown case */
508bac5051cSeric putchar('\\');
509bac5051cSeric putchar(*lp);
510bac5051cSeric break;
511bac5051cSeric }
512bac5051cSeric }
513bac5051cSeric else putchar(*lp);
514bac5051cSeric }
515bac5051cSeric }
516bac5051cSeric /*
517bac5051cSeric zero out first char of global string lines in case
518bac5051cSeric a value is not gotten in next delta table entry
519bac5051cSeric */
520bac5051cSeric iline[0] = xline[0] = gline[0] = 0;
521bac5051cSeric putchar('\n');
522bac5051cSeric return;
523bac5051cSeric }
524bac5051cSeric
525bac5051cSeric
clean_up()526bac5051cSeric clean_up()
527bac5051cSeric {
528bac5051cSeric unlink(untmp);
529bac5051cSeric unlink(uttmp);
530bac5051cSeric unlink(bdtmp);
5314a6a95bbSeric if (gpkt.p_iop)
5324a6a95bbSeric fclose(gpkt.p_iop);
533bac5051cSeric }
534bac5051cSeric
535bac5051cSeric
536bac5051cSeric /* This function takes as it's argument the SID inputed and determines
537bac5051cSeric * whether or not it is valid (e. g. not ambiguous or illegal).
538bac5051cSeric */
invalid(i_sid)539bac5051cSeric invalid(i_sid)
540bac5051cSeric register char *i_sid;
541bac5051cSeric {
542bac5051cSeric register int count;
543bac5051cSeric register int digits;
544bac5051cSeric count = digits = 0;
545bac5051cSeric if (*i_sid == '0' || *i_sid == '.')
546bac5051cSeric return (1);
547bac5051cSeric i_sid++;
548bac5051cSeric digits++;
549bac5051cSeric while (*i_sid != '\0') {
550bac5051cSeric if (*i_sid++ == '.') {
551bac5051cSeric digits = 0;
552bac5051cSeric count++;
553bac5051cSeric if (*i_sid == '0' || *i_sid == '.')
554bac5051cSeric return (1);
555bac5051cSeric }
556bac5051cSeric digits++;
557bac5051cSeric if (digits > 5)
558bac5051cSeric return (1);
559bac5051cSeric }
560bac5051cSeric if (*(--i_sid) == '.' )
561bac5051cSeric return (1);
562bac5051cSeric if (count == 1 || count == 3)
563bac5051cSeric return (0);
564bac5051cSeric return (1);
565bac5051cSeric }
566bac5051cSeric
567bac5051cSeric
deltblchk(pkt)568bac5051cSeric deltblchk(pkt)
569bac5051cSeric register struct packet *pkt;
570bac5051cSeric {
571bac5051cSeric int n;
572bac5051cSeric struct deltab dt;
573bac5051cSeric struct stats stats;
574bac5051cSeric
575bac5051cSeric /*
576bac5051cSeric Read entire delta table.
577bac5051cSeric */
578bac5051cSeric while (getstats(pkt,&stats)) {
579bac5051cSeric if (getadel(pkt,&dt) != BDELTAB)
580bac5051cSeric fmterr(pkt);
581bac5051cSeric
582bac5051cSeric /*
583bac5051cSeric Read rest of delta entry.
584bac5051cSeric */
585bac5051cSeric while ((n = getline(pkt)) != NULL)
586bac5051cSeric if (pkt->p_line[0] != CTLCHAR)
587bac5051cSeric break;
588bac5051cSeric else {
589bac5051cSeric switch (pkt->p_line[1]) {
590bac5051cSeric case EDELTAB:
591bac5051cSeric break;
592bac5051cSeric case INCLUDE:
593bac5051cSeric case EXCLUDE:
594bac5051cSeric case IGNORE:
595bac5051cSeric case MRNUM:
596bac5051cSeric case COMMENTS:
597bac5051cSeric continue;
598bac5051cSeric default:
599bac5051cSeric fmterr(pkt);
600bac5051cSeric }
601bac5051cSeric break;
602bac5051cSeric }
603bac5051cSeric if (n == NULL || pkt->p_line[0] != CTLCHAR)
604bac5051cSeric fmterr(pkt);
605bac5051cSeric }
606bac5051cSeric if (pkt->p_line[1] != BUSERNAM)
607bac5051cSeric fmterr(pkt);
608bac5051cSeric }
609bac5051cSeric
610bac5051cSeric
getstats(pkt,statp)611bac5051cSeric getstats(pkt,statp)
612bac5051cSeric register struct packet *pkt;
613bac5051cSeric register struct stats *statp;
614bac5051cSeric {
615bac5051cSeric register char *p;
616bac5051cSeric
617bac5051cSeric p = pkt->p_line;
618bac5051cSeric if (getline(pkt) == NULL || *p++ != CTLCHAR || *p++ != STATS)
619bac5051cSeric return(0);
620bac5051cSeric NONBLANK(p);
621bac5051cSeric p = satoi(p,&statp->s_ins);
622bac5051cSeric p = satoi(++p,&statp->s_del);
623bac5051cSeric satoi(++p,&statp->s_unc);
624bac5051cSeric return(1);
625bac5051cSeric }
626bac5051cSeric
627bac5051cSeric
getadel(pkt,dt)628bac5051cSeric getadel(pkt,dt)
629bac5051cSeric register struct packet *pkt;
630bac5051cSeric register struct deltab *dt;
631bac5051cSeric {
632bac5051cSeric if (getline(pkt) == NULL)
633bac5051cSeric fmterr(pkt);
634bac5051cSeric return(del_ab(pkt->p_line,dt,pkt));
635bac5051cSeric }
636bac5051cSeric
637bac5051cSeric
638bac5051cSeric
maket(file)639bac5051cSeric char *maket(file)
640bac5051cSeric char *file;
641bac5051cSeric {
642bac5051cSeric FILE *iop;
643bac5051cSeric
644bac5051cSeric copy(tempskel,file);
645bac5051cSeric iop = xfcreat(mktemp(file),0644);
646bac5051cSeric
647bac5051cSeric return(iop);
648bac5051cSeric }
649bac5051cSeric
650bac5051cSeric
printfile(file)651bac5051cSeric printfile(file)
652bac5051cSeric register char *file;
653bac5051cSeric {
654bac5051cSeric register char *p;
655bac5051cSeric FILE *iop;
656bac5051cSeric
657bac5051cSeric iop = xfopen(file,0);
658bac5051cSeric while ((p = fgets(line,sizeof(line),iop)) != NULL)
659bac5051cSeric printf("%s",p);
660bac5051cSeric fclose(iop);
661bac5051cSeric }
662bac5051cSeric
663bac5051cSeric
read_mod(pkt)664bac5051cSeric read_mod(pkt)
665bac5051cSeric register struct packet *pkt;
666bac5051cSeric {
667bac5051cSeric register char *p;
668bac5051cSeric int ser;
669bac5051cSeric int iord;
670bac5051cSeric register struct apply *ap;
671bac5051cSeric
672bac5051cSeric BDiop = maket(bdtmp);
673bac5051cSeric while (getline(pkt) != NULL) {
674bac5051cSeric p = pkt->p_line;
675bac5051cSeric fputs(p,BDiop);
676bac5051cSeric if (*p++ != CTLCHAR)
677bac5051cSeric continue;
678bac5051cSeric else {
679bac5051cSeric if (!((iord = *p++) == INS || iord == DEL || iord == END))
680bac5051cSeric fmterr(pkt);
681bac5051cSeric NONBLANK(p);
682bac5051cSeric satoi(p,&ser);
683bac5051cSeric if (iord == END)
684bac5051cSeric remq(pkt,ser);
685bac5051cSeric else if ((ap = &pkt->p_apply[ser])->a_code == APPLY)
686bac5051cSeric addq(pkt,ser,iord == INS ? YES : NO,iord,ap->a_reason & USER);
687bac5051cSeric else
688bac5051cSeric addq(pkt,ser,iord == INS ? NO : NULL,iord,ap->a_reason & USER);
689bac5051cSeric }
690bac5051cSeric }
691bac5051cSeric fclose(BDiop);
692bac5051cSeric if (pkt->p_q)
693bac5051cSeric fatal("premature eof (co5)");
694bac5051cSeric return(0);
695bac5051cSeric }
696bac5051cSeric
697bac5051cSeric
698bac5051cSeric getbody(gsid,pkt)
699bac5051cSeric struct sid *gsid;
700bac5051cSeric struct packet *pkt;
701bac5051cSeric {
702bac5051cSeric int i;
703bac5051cSeric int status;
704bac5051cSeric char str[128];
705bac5051cSeric char rarg[20];
706bac5051cSeric char filearg[80];
707bac5051cSeric
708bac5051cSeric sid_ba(gsid,str);
709bac5051cSeric sprintf(rarg,"%s",str);
710bac5051cSeric sprintf(filearg,"%s",pkt->p_file);
711bac5051cSeric /*
712bac5051cSeric fork here so 'getbody' can execute 'get' to
713bac5051cSeric print out gotten body :GB:
714bac5051cSeric */
715bac5051cSeric if ((i = fork()) < 0)
716bac5051cSeric fatal("cannot fork, try again");
717bac5051cSeric if (i = 0) {
718bac5051cSeric /*
719bac5051cSeric perform 'get' and redirect output
720bac5051cSeric to standard output
721bac5051cSeric */
722*19db951cSbostic execl(_PATH_GET,"get","-s","-p","-r",rarg,filearg,0);
723*19db951cSbostic sprintf(Error,"cannot execute '%s'",_PATH_GET);
724824dd99bSbostic fatal(Error);
725bac5051cSeric }
726bac5051cSeric else {
727bac5051cSeric wait(&status);
728bac5051cSeric return;
729bac5051cSeric }
730bac5051cSeric }
731bac5051cSeric
732bac5051cSeric
getit(str,cp)733bac5051cSeric getit(str,cp)
734bac5051cSeric register char *str, *cp;
735bac5051cSeric {
7365b29b8bcSlepreau cp += 2;
737bac5051cSeric NONBLANK(cp);
738bac5051cSeric cp[length(cp) - 1] = '\0';
739bac5051cSeric sprintf(str,"%s",cp);
740bac5051cSeric }
741bac5051cSeric
742bac5051cSeric
aux_create(iop,file,delchar)743bac5051cSeric aux_create(iop,file,delchar)
744bac5051cSeric FILE *iop;
745bac5051cSeric char *file;
746bac5051cSeric char delchar;
747bac5051cSeric {
748bac5051cSeric
749bac5051cSeric int n;
750bac5051cSeric int text;
751bac5051cSeric /*
752bac5051cSeric create auxiliary file for the named section
753bac5051cSeric */
754bac5051cSeric
755bac5051cSeric text = 0;
756bac5051cSeric iop = maket(file);
757bac5051cSeric while ((n = getline(&gpkt)) != NULL && gpkt.p_line[0] != CTLCHAR) {
758bac5051cSeric text = 1;
759bac5051cSeric fputs(n,iop);
760bac5051cSeric }
761bac5051cSeric /*
762bac5051cSeric check to see that delimiter found is correct
763bac5051cSeric */
764bac5051cSeric if (n == NULL || gpkt.p_line[0] != CTLCHAR || gpkt.p_line[1] != delchar)
765bac5051cSeric fmterr(&gpkt);
766bac5051cSeric if (!text)
767bac5051cSeric fprintf(iop,"No entries\n");
768bac5051cSeric fclose(iop);
769bac5051cSeric }
770bac5051cSeric
771bac5051cSeric
772bac5051cSeric idsetup(gsid,pkt,bdate)
773bac5051cSeric struct sid *gsid;
774bac5051cSeric struct packet *pkt;
775bac5051cSeric long *bdate;
776bac5051cSeric {
777bac5051cSeric
778bac5051cSeric register char *p;
7794a6a95bbSeric extern struct tm *localtime();
780bac5051cSeric
781bac5051cSeric date_ba(bdate,Deltadate);
782bac5051cSeric
783bac5051cSeric Deltatime = &Deltadate[9];
784bac5051cSeric Deltadate[8] = 0;
785bac5051cSeric
786bac5051cSeric sid_ba(gsid,Sid);
787bac5051cSeric
788bac5051cSeric Dtime = localtime(bdate);
789bac5051cSeric
790bac5051cSeric if (p = Sflags[MODFLAG - 'a'])
791bac5051cSeric copy(p,Mod);
792bac5051cSeric else sprintf(Mod,"%s",sname(pkt->p_file));
793bac5051cSeric
794bac5051cSeric if (!(Type = Sflags[TYPEFLAG - 'a']))
795bac5051cSeric Type = "none";
796bac5051cSeric }
797