/*************************************************************************/
/* */
/* prs [-d<dataspec>] [-r<sid>] [-l] [-e] [-a] file ... */
/* */
/*************************************************************************/
/*
Program to print parts or all of an SCCS file
in user supplied format.
Arguments to the program may appear in any order
and consist of keyletters, which begin with '-',
and named files.
If a direcory is given as an argument, each
SCCS file within the directory is processed as if
it had been specifically named. If a name of '-'
is given, the standard input is read for a list
of names of SCCS files to be processed.
Non-SCCS files are ignored.
*/
# include "../hdr/defines.h"
# include "../hdr/had.h"
SCCSID(@(#)prs.c 1.12 88/05/03 SMI); /* from System III 5.1 */
USXALLOC(); /* use of xalloc instead of alloc */
char Getpgm[] = "/usr/sccs/get";
static char defline[] = ":Dt:\t:DL:\nMRs:\n:MR:COMMENTS:\n:C:";
char Sid[32];
char Mod[FILESIZE];
char Olddir[BUFSIZ];
char Pname[BUFSIZ];
char Dir[BUFSIZ];
char *Type;
char *Qsect;
char Deltadate[18];
char *Deltatime;
char *getline();
char tempskel[] = "/tmp/prXXXXXX"; /* used to generate temp
file names
*/
char untmp[32], uttmp[32], cmtmp[32];
char mrtmp[32], bdtmp[32];
FILE *UNiop;
FILE *UTiop;
FILE *CMiop;
FILE *MRiop;
FILE *BDiop;
FILE *fdfopen();
char line[BUFSIZ];
int num_files;
int HAD_CM, HAD_MR, HAD_FD, HAD_BD, HAD_UN;
char dt_line[BUFSIZ];
char *dataspec = &defline[0];
char iline[BUFSIZ], xline[BUFSIZ], gline[BUFSIZ];
FILE *maket();
struct packet gpkt;
struct sid sid;
struct tm *Dtime;
long Date_time;
main(argc,argv)
int argc;
char *argv[];
{
register int j;
register char *p;
char c;
extern process();
extern int Fcnt;
/*
Set flags for 'fatal' to issue message, call clean-up
routine, and terminate processing.
*/
Fflags = FTLMSG | FTLCLN | FTLEXIT;
/*
The following loop processes keyletters and arguments.
Note that these are processed only once for each
invocation of 'main'.
*/
for (j = 1; j < argc; j++)
if (argv[j][0] == '-' && (c = argv[j][1])) {
p = &argv[j][2];
switch (c) {
case 'r': /* specified SID */
if (*p) {
if (invalid(p))
fatal("invalid sid (co8)");
sid_ab(p,&sid);
}
break;
case 'c': /* cutoff date[time] */
if ((*p) && (date_ab(p, &Date_time) != -1))
break;
else
fatal("invalid cutoff date");
case 'l': /* later than specified SID */
case 'e': /* earlier than specified SID */
case 'a': /* print all delta types (R or D) */
case 'q': /* enable NSE mode */
if (*p) {
nsedelim = p;
} else {
nsedelim = (char *) 0;
}
break;
case 'd': /* dataspec line */
if (*p)
dataspec = p;
break;
default:
fatal("unknown key letter (cm1)");
}
if (had[c - 'a']++)
fatal("key letter twice (cm2)");
argv[j] = 0;
}
else
num_files++;
if (num_files == 0)
fatal("missing file arg (cm3)");
if (HADR && HADC)
fatal("can't specify cutoff date and SID");
if (HADC && (!HADL) && (!HADE))
fatal("must specify -e or -l with -c");
/*
check the dataspec line and determine if any tmp files
need be created
*/
ck_spec(dataspec);
setsig();
/*
Change flags for 'fatal' so that it will return to this
routine (main) instead of terminating processing.
*/
Fflags &= ~FTLEXIT;
Fflags |= FTLJMP;
/*
Call 'process' routine for each file argument.
*/
for (j = 1; j < argc; j++)
if (p = argv[j])
do_file(p,process);
exit(Fcnt ? 1 : 0);
/* NOTREACHED */
}
/*
* This procedure opens the SCCS file and calls all subsequent
* modules to perform 'prs'. Once the file is finished, process
* returns to 'main' to process any other possible files.
*/
process(file)
register char *file;
{
static int pr_fname = 0;
extern char had_dir, had_standinp;
if (setjmp(Fjmp)) /* set up to return here from 'fatal' */
return; /* and return to caller of 'process' */
sinit(&gpkt,file,1); /* init packet and open SCCS file */
/*
move value of global sid into gpkt.p_reqsid for
later comparision.
*/
move(&sid,&gpkt.p_reqsid,sizeof(sid));
gpkt.p_reopen = 1; /* set reopen flag to 1 for 'getline' */
/*
Read delta table entries checking for format error and
setting the value for the SID if none was specified.
Also check to see if SID specified does in fact exists.
*/
deltblchk(&gpkt);
/*
create auxiliary file for User Name Section
*/
if (HAD_UN)
aux_create(UNiop,untmp,EUSERNAM);
else read_to(EUSERNAM,&gpkt);
/*
store flags (if any) into global array called 'Sflags'
*/
doflags(&gpkt);
/*
create auxiliary file for the User Text section
*/
if (HAD_FD)
aux_create(UTiop,uttmp,EUSERTXT);
else read_to(EUSERTXT,&gpkt);
/*
indicate to 'getline' that EOF is okay
*/
gpkt.p_chkeof = 1;
/*
read body of SCCS file and create temp file for it
*/
while(read_mod(&gpkt))
;
/*
Here, file has already been re-opened (by 'getline' after
EOF was encountered by 'read_mod' calling 'getline')
*/
getline(&gpkt); /* skip over header line */
if (!HADD && !HADR && !HADE && !HADL)
HADE = pr_fname = 1;
if (pr_fname)
printf("%s:\n\n",nse_file_trim(file, 0));
/*
call 'dodeltbl' to read delta table entries
and determine which deltas are to be considered
*/
dodeltbl(&gpkt);
/*
call 'clean_up' to remove any temporary file created
during processing of the SCCS file passed as an argument from
'do_file'
*/
clean_up();
return; /* return to caller of 'process' */
}
/*
* This procedure actually reads the delta table entries and
* substitutes pre-defined strings and pointers with the information
* needed during the scanning of the 'dataspec' line
*/
dodeltbl(pkt)
register struct packet *pkt;
{
char *n;
int stopdel;
int found;
long dcomp;
struct deltab dt;
struct stats stats;
/*
flags used during determination of deltas to be
considered
*/
found = stopdel = 0;
/*
Read entire delta table.
*/
while (getstats(pkt,&stats) && !stopdel) {
if (getadel(pkt,&dt) != BDELTAB)
fmterr(pkt);
/*
ignore 'removed' deltas if !HADA keyletter
*/
if (!HADA && dt.d_type != 'D') {
read_to(EDELTAB,pkt);
continue;
}
/*
determine whether or not to consider current delta
*/
if (HADC) {
dcomp = Date_time - dt.d_datetime;
if (HADE && !HADL && (dcomp < 0)) {
read_to(EDELTAB, pkt);
continue;
}
else if (HADL && !HADE && (dcomp > 0)) {
stopdel = 1;
continue;
}
}
else if (HADE && HADL) stopdel = 0;
else if (!(eqsid(&gpkt.p_reqsid, &dt.d_sid)) && !found) {
/*
if !HADL keyletter skip delta entry
*/
if (!HADL) {
read_to(EDELTAB,pkt);
continue;
}
}
else {
found = 1;
stopdel = 1;
}
/*
if HADE keyletter read remainder of delta table entries
*/
if (HADE && stopdel)
stopdel = 0;
/*
create temp file for MRs and comments
*/
if (HAD_MR)
MRiop = maket(mrtmp);
if (HAD_CM)
CMiop = maket(cmtmp);
/*
Read rest of delta entry.
*/
while ((n = getline(pkt)) != NULL)
if (pkt->p_line[0] != CTLCHAR)
break;
else {
switch (pkt->p_line[1]) {
case INCLUDE:
getit(iline,n);
continue;
case EXCLUDE:
getit(xline,n);
continue;
case IGNORE:
getit(gline,n);
continue;
case MRNUM:
if (HAD_MR)
putmr(n);
continue;
case COMMENTS:
if (HAD_CM)
putcom(n);
continue;
case EDELTAB:
/*
close temp files for MRs and comments
*/
if (HAD_MR)
fclose(MRiop);
if (HAD_CM)
fclose(CMiop);
scanspec(dataspec,&dt,&stats);
/*
remove temp files for MRs and comments
*/
unlink(mrtmp);
unlink(cmtmp);
break;