4f52437ea440b6bb833697ae3c430f84a1694006
/************************************************************************/
/* val [-mname] [-rSID] [-s] [-ytype] file ... */
/************************************************************************/
# include "../hdr/defines.h"
# define FILARG_ERR 0200 /* no file name given */
# define UNKDUP_ERR 0100 /* unknown or duplicate keyletter */
# define CORRUPT_ERR 040 /* corrupt file error code */
# define FILENAM_ERR 020 /* file name error code */
# define INVALSID_ERR 010 /* invalid or ambiguous SID error */
# define NONEXSID_ERR 04 /* non-existent SID error code */
# define TYPE_ERR 02 /* type arg value error code */
# define NAME_ERR 01 /* name arg value error code */
# define BLANK(l) while (!(*l == ' ' || *l == '\t')) l++;
int ret_code
; /* prime return code from 'main' program */
int inline_err
; /* input line error code (from 'process') */
int infile_err
; /* file error code (from 'validate') */
int inpstd
; /* TRUE = args from standard input */
char had
[26]; /* had flag used in 'process' function */
char path
[50]; /* storage for file name value */
char sid
[50]; /* storage for sid (-r) value */
char type
[50]; /* storage for type (-y) value */
char name
[50]; /* storage for name (-m) value */
char *get_line(); /* function returning ptr to line read */
char *getval(); /* function returning adjusted ptr to line */
char *alloc(); /* function returning ptr */
char *fgets(); /* function returning i/o ptr */
struct delent
{ /* structure for delta table entry */
/* This is the main program that determines whether the command line
* comes from the standard input or read off the original command
* line. See VAL(I) for more information.
if (argc
== 2 && argv
[1][0] == '-' && !(argv
[1][1])) {
iop
= stdin
; /* read from standard input */
while (fgets(line
,BUFSIZ
,iop
) != NULL
) {
for (j
= 1; j
< argc
; j
++)
sprintf(&(line
[strlen(line
)]),"%s ",argv
[j
]);
line
[j
> 0 ? j
: 0] = NULL
;
/* This function processes the line sent by the main routine. It
* determines which keyletter values are present on the command
* line and assigns the values to the correct storage place. It
* then calls validate for each file name on the command line
* It will return to main if the input line contains an error,
* otherwise it returns any error code found by validate.
path
[0] = sid
[0] = type
[0] = name
[0] = 0;
num_files
= inline_err
= 0;
make copy of 'line' for use later
clear out had flags for each 'line' processed
execute loop until all characters in 'line' are checked.
p_line
= getval(p_line
,sid
);
p_line
= getval(p_line
,type
);
p_line
= getval(p_line
,name
);
inline_err
=| UNKDUP_ERR
;
use 'had' array and determine if the keyletter
if (had
[c
- 'a']++ && testklt
++)
inline_err
=| UNKDUP_ERR
;
assume file name if no '-' preceeded argument
p_line
= getval(p_line
,filelist
[num_files
]);
check if any files were named as arguments
inline_err
=| FILARG_ERR
;
check for error in command line.
if (inline_err
&& !silent
) {
report(inline_err
,savelinep
,"");
else report(inline_err
,"","");
return; /* return to 'main' routine */
line_sw
= 1; /* print command line flag */
loop through 'validate' for each file on command line.
for (j
= 0; j
< num_files
; j
++) {
read a file from 'filelist' and place into 'path'.
sprintf(path
,"%s",filelist
[j
]);
validate(path
,sid
,type
,name
);
inline_err
=| infile_err
;
check for error from 'validate' and call 'report'
depending on 'silent' flag.
if (infile_err
&& !silent
) {
report(infile_err
,savelinep
,path
);
else report(infile_err
,"",path
);
return; /* return to 'main' routine */
/* This function actually does the validation on the named file.
* It determines whether the file is an SCCS-file or if the file
* exists. It also determines if the values given for type, SID,
* and name match those in the named file. An error code is returned
* if any mismatch occurs. See VAL(I) for more information.
validate(c_path
,c_sid
,c_type
,c_name
)
int goods
,goodt
,goodn
,hadmflag
;
infile_err
= goods
= goodt
= goodn
= hadmflag
= 0;
if (!sccsfile(c_path
) || (gpkt
.p_iop
= fopen(c_path
,"r")) == NULL
)
infile_err
=| FILENAM_ERR
;
l
= get_line(&gpkt
); /* read first line in file */
check that it is header line.
if (*l
++ != CTLCHAR
|| *l
++ != HEAD
)
infile_err
=| CORRUPT_ERR
;
get old file checksum count
check for invalid or ambiguous SID.
infile_err
=| INVALSID_ERR
;
read delta table checking for errors and/or
if (do_delt(&gpkt
,goods
,c_sid
)) {
infile_err
=| CORRUPT_ERR
;
read flag section of delta table.
while ((l
= get_line(&gpkt
)) &&
else if (*l
== MODFLAG
) {
if (*(--l
) != BUSERTXT
) {
infile_err
=| CORRUPT_ERR
;
check if 'y' flag matched '-y' arg value.
check if 'm' flag matched '-m' arg value.
if (!equal(auxf(sname(c_path
),'g'),c_name
))
else if (HADM
&& hadmflag
&& !goodn
)
else read_to(BUSERTXT
,&gpkt
);
read remainder of file so 'read_mod'
can check for corruptness.
fclose(gpkt
.p_iop
); /* close file pointer */
return; /* return to 'process' function */
/* This function reads the 'delta' line from the named file and stores
* the information into the structure 'del'.
register struct delent
*delp
;
/* This function does a read through the named file until it finds
* the character sent over as an argument.
register struct packet
*pkt
;
while ((n
= get_line(pkt
)) &&
!(*n
++ == CTLCHAR
&& *n
== ch
))
/* This function places into a specified destination characters which
* are delimited by either a space, tab or 0. It obtains the char-
* acters from a line of characters.
char *getval(sourcep
,destp
)
while (*sourcep
!= ' ' && *sourcep
!= '\t' && *sourcep
!= '\0')
/* This function will report the error that occured on the command
* line. It will print one diagnostic message for each error that
* was found in the named file.
report(code
,inp_line
,file
)
percent
= '%'; /* '%' for -m and/or -y messages */
printf("%s\n\n",inp_line
);
printf(" %s: %cM%c, -m mismatch\n",file
,percent
,percent
);
printf(" %s: %cY%c, -y mismatch\n",file
,percent
,percent
);
printf(" %s: SID nonexistent\n",file
);
printf(" %s: SID invalid or ambiguous\n",file
);
printf(" %s: can't open file or file not SCCS\n",file
);
printf(" %s: corrupted SCCS file\n",file
);
printf(" %s: Unknown or dupilcate keyletter argument\n",file
);
printf(" %s: missing file argument\n",file
);
/* This function takes as it's argument the SID inputed and determines
* whether or not it is valid (e. g. not ambiguous or illegal).
if (*i_sid
== '0' || *i_sid
== '.')
if (*i_sid
== '0' || *i_sid
== '.')
if (count
== 1 || count
== 3)
Routine to read a line into the packet. The main reason for
it is to make sure that pkt->p_wrttn gets turned off,
and to increment pkt->p_slnno.
register struct packet
*pkt
;
if ((n
= fgets(pkt
->p_line
,sizeof(pkt
->p_line
),pkt
->p_iop
)) != NULL
) {
for (p
= pkt
->p_line
; *p
; )
infile_err
=| CORRUPT_ERR
;
if (pkt
->do_chksum
&& (pkt
->p_chash
^ pkt
->p_ihash
)&0xFFFF)
infile_err
=| CORRUPT_ERR
;
Does initialization for sccs files and packet.
register struct packet
*pkt
;
pkt
->do_chksum
= 1; /* turn on checksum check for getline */
register struct packet
*pkt
;
register struct apply
*ap
;
while (get_line(pkt
) != NULL
) {
if (!((iord
= *p
++) == INS
|| iord
== DEL
|| iord
== END
)) {
infile_err
=| CORRUPT_ERR
;
else if ((ap
= &pkt
->p_apply
[ser
])->a_code
== APPLY
)
addq(pkt
,ser
,iord
== INS
? YES
: NO
,iord
,ap
->a_reason
& USER
);
addq(pkt
,ser
,iord
== INS
? NO
: NULL
,iord
,ap
->a_reason
& USER
);
infile_err
=| CORRUPT_ERR
;
addq(pkt
,ser
,keep
,iord
,user
)
register struct queue
*cur
, *prev
, *q
;
for (cur
= &pkt
->p_q
; cur
= (prev
= cur
)->q_next
; )
if (cur
->q_sernum
<= ser
)
if (cur
->q_sernum
== ser
)
infile_err
=| CORRUPT_ERR
;
prev
->q_next
= q
= alloc(sizeof(*q
));
if (pkt
->p_ixuser
&& (q
->q_ixmsg
= chkix(q
,&pkt
->p_q
)))
register struct packet
*pkt
;
register struct queue
*cur
, *prev
;
for (cur
= &pkt
->p_q
; cur
= (prev
= cur
)->q_next
; )
if (cur
->q_sernum
== ser
)
prev
->q_next
= cur
->q_next
;
infile_err
=| CORRUPT_ERR
;
register struct packet
*pkt
;
register struct queue
*q
;
for (q
= &pkt
->p_q
; q
= q
->q_next
; )
if ((pkt
->p_keep
= q
->q_keep
) == YES
) {
sp
= &pkt
->p_idel
[q
->q_sernum
].i_sid
;
pkt
->p_inssid
.s_rel
= sp
->s_rel
;
pkt
->p_inssid
.s_lev
= sp
->s_lev
;
pkt
->p_inssid
.s_br
= sp
->s_br
;
pkt
->p_inssid
.s_seq
= sp
->s_seq
;
# define apply(qp) ((qp->q_iord == INS && qp->q_keep == YES) || (qp->q_iord == DEL && qp->q_keep == NO))
register struct queue
*new;
register struct queue
*cur
;
for (cur
= head
; cur
= cur
->q_next
; )
for (cur
= head
; cur
= cur
->q_next
; ) {
firstins
= cur
->q_sernum
;
else if (cur
->q_iord
== INS
)
if (lastdel
&& (new->q_sernum
> lastdel
))
if (firstins
&& (new->q_sernum
< firstins
))
/* This function reads the delta table entries and checks for the format
* as specifed in sccsfile(V). If the format is incorrect, a corrupt
* error will be issued by 'val'. This function also checks
* if the sid requested is in the file (depending if '-r' was specified).
register struct packet
*pkt
;
if ((l
= get_line(pkt
)) && *l
++ != CTLCHAR
|| *l
++ != BDELTAB
)
if (HADR
&& !(infile_err
& INVALSID_ERR
)) {
if (equal(d_sid
,del
.osid
) && del
.type
== 'D')
while ((l
= get_line(pkt
)) != NULL
)
if (pkt
->p_line
[0] != CTLCHAR
)
if (l
== NULL
|| pkt
->p_line
[0] != CTLCHAR
)
if (pkt
->p_line
[1] != BUSERNAM
)
if (HADR
&& !goods
&& !(infile_err
& INVALSID_ERR
))
infile_err
=| NONEXSID_ERR
;
/* This function reads the stats line from the sccsfile */
register struct packet
*pkt
;
if (get_line(pkt
) == NULL
|| *p
++ != CTLCHAR
|| *p
!= STATS
)