static char SccsId
[] = "@(#)sccs.c 1.9 delta %G% 12:31:38 get %H% %T%";
# define bitset(bit, word) ((bit) & (word))
char *sccsname
; /* name of SCCS routine */
short sccsoper
; /* opcode, see below */
short sccsflags
; /* flags, see below */
char *sccspath
; /* pathname of binary implementing */
/* values for sccsoper */
# define PROG 0 /* call a program */
# define CMACRO 1 /* command substitution macro */
# define NO_SDOT 0001 /* no s. on front of args */
# define REALUSER 0002 /* protected (e.g., admin) */
# define PROGPATH(name) "/usr/local/name"
# define PROGPATH(name) "/usr/sccs/name"
struct sccsprog SccsProg
[] =
"admin", PROG
, REALUSER
, PROGPATH(admin
),
"chghist", PROG
, 0, PROGPATH(rmdel
),
"comb", PROG
, 0, PROGPATH(comb
),
"delta", PROG
, 0, PROGPATH(delta
),
"get", PROG
, 0, PROGPATH(get
),
"help", PROG
, NO_SDOT
, PROGPATH(help
),
"prt", PROG
, 0, PROGPATH(prt
),
"rmdel", PROG
, REALUSER
, PROGPATH(rmdel
),
"what", PROG
, NO_SDOT
, PROGPATH(what
),
"del", CMACRO
, 0, "delta/get",
char *SccsPath
= "SCCS"; /* pathname of SCCS files */
bool RealUser
; /* if set, running as real user */
** Detect and decode flags intended for this program.
fprintf(stderr
, "Usage: sccs [flags] command [flags]\n");
while ((p
= *++argv
) != NULL
)
case 'r': /* run as real user */
case 'p': /* path of sccs files */
fprintf(stderr
, "Sccs: unknown option -%s\n", p
);
register struct sccsprog
*cmd
;
** At this point, argv points to the command name.
for (cmd
= SccsProg
; cmd
->sccsname
!= NULL
; cmd
++)
if (strcmp(cmd
->sccsname
, p
) == 0)
if (cmd
->sccsname
== NULL
)
fprintf(stderr
, "Sccs: Unknown command \"%s\"\n", p
);
** Interpret operation associated with this command.
case PROG
: /* call an sccs prog */
callprog(cmd
->sccspath
, cmd
->sccsflags
, argv
, forkflag
);
case CMACRO
: /* command macro */
for (p
= cmd
->sccspath
; *p
!= '\0'; p
++)
for (q
= buf
; *p
!= '/' && *p
!= '\0'; p
++, q
++)
command(argv
, *p
!= '\0');
fprintf(stderr
, "Sccs internal error: CMACRO\n");
fprintf(stderr
, "Sccs internal error: oper %d\n", cmd
->sccsoper
);
callprog(progpath
, flags
, argv
, forkflag
)
** Build new argument vector.
/* copy program filename arguments and flags */
while ((p
= *++argv
) != NULL
)
if (!bitset(NO_SDOT
, flags
) && *p
!= '-')
/* terminate argument vector */
** Call real SCCS program.
fprintf(stderr
, "Sccs: cannot fork");
** Set protection as appropriate.
if (bitset(REALUSER
, flags
))
execv(progpath
, newargv
);
fprintf(stderr
, "Sccs: cannot execute ");
** See if this filename should be used as-is.
** There are three conditions where this can occur.
** 1. The name already begins with "s.".
** 2. The name has a "/" in it somewhere.
** 3. The name references a directory.
if (strncmp(name
, "s.", 2) == 0)
for (p
= name
; (c
= *p
) != '\0'; p
++)
if (stat(name
, &stbuf
) >= 0 && (stbuf
.st_mode
& S_IFMT
) == S_IFDIR
)
** Prepend the path of the sccs file.
p
= malloc(strlen(buf
) + 1);