1148Seric # include <stdio.h> 2148Seric # include <sys/types.h> 3148Seric # include <sys/stat.h> 4148Seric # include <sysexits.h> 5148Seric 6*155Seric static char SccsId[] = "@(#)sccs.c 1.3 delta 05/13/80 00:27:33 get 10/14/12 16:33:33"; 7*155Seric 8148Seric struct sccsprog 9148Seric { 10148Seric char *sccsname; /* name of SCCS routine */ 11148Seric short sccsflags; /* see below */ 12148Seric char *sccspath; /* pathname of binary implementing */ 13148Seric }; 14148Seric 15148Seric /* bits for sccspath */ 16148Seric # define F_NOSDOT 0001 /* no s. on front of args */ 17148Seric 18148Seric struct sccsprog SccsProg[] = 19148Seric { 20148Seric "admin", 0, "/usr/sccs/admin", 21153Seric "chghist", 0, "/usr/sccs/rmdel", 22148Seric "comb", 0, "/usr/sccs/comb", 23148Seric "delta", 0, "/usr/sccs/delta", 24148Seric "get", 0, "/usr/sccs/get", 25153Seric "help", F_NOSDOT, "/usr/sccs/help", 26148Seric "prt", 0, "/usr/sccs/prt", 27148Seric "rmdel", 0, "/usr/sccs/rmdel", 28148Seric "what", F_NOSDOT, "/usr/sccs/what", 29148Seric NULL, 0, NULL 30148Seric }; 31148Seric 32153Seric char *SccsPath = "SCCS/s."; 33148Seric 34148Seric main(argc, argv) 35148Seric int argc; 36148Seric char **argv; 37148Seric { 38148Seric register char *p; 39148Seric register char **av; 40148Seric char *newargv[1000]; 41148Seric extern char *makefile(); 42148Seric register struct sccsprog *cmd; 43148Seric 44148Seric /* 45148Seric ** Detect and decode flags intended for this program. 46148Seric */ 47148Seric 48148Seric while (--argc > 0) 49148Seric { 50148Seric p = *++argv; 51148Seric if (*p != '-') 52148Seric break; 53148Seric switch (*++p) 54148Seric { 55148Seric case 'r': /* run as real user */ 56148Seric setuid(getuid()); 57148Seric break; 58148Seric 59148Seric case 'p': /* path of sccs files */ 60148Seric SccsPath = ++p; 61148Seric break; 62148Seric 63148Seric default: 64148Seric fprintf(stderr, "Sccs: unknown option -%s\n", p); 65148Seric break; 66148Seric } 67148Seric } 68148Seric 69148Seric /* 70148Seric ** Look up command. 71148Seric ** At this point, p and argv point to the command name. 72148Seric */ 73148Seric 74148Seric for (cmd = SccsProg; cmd->sccsname != NULL; cmd++) 75148Seric { 76148Seric if (strcmp(cmd->sccsname, p) == 0) 77148Seric break; 78148Seric } 79148Seric if (cmd->sccsname == NULL) 80148Seric { 81148Seric fprintf(stderr, "Sccs: Unknown command \"%s\"\n", p); 82148Seric exit(EX_USAGE); 83148Seric } 84148Seric 85148Seric /* 86148Seric ** Build new argument vector. 87148Seric */ 88148Seric 89148Seric av = newargv; 90148Seric *av++ = p; 91148Seric 92153Seric /* copy program filename arguments and flags */ 93153Seric while (--argc > 0) 94148Seric { 95153Seric p = *++argv; 96153Seric if ((cmd->sccsflags & F_NOSDOT) == 0 && *p != '-') 97153Seric *av++ = makefile(p); 98148Seric else 99153Seric *av++ = p; 100148Seric } 101148Seric 102148Seric /* terminate argument vector */ 103148Seric *av = NULL; 104148Seric 105148Seric /* 106148Seric ** Call real SCCS program. 107148Seric */ 108148Seric 109148Seric execv(cmd->sccspath, newargv); 110148Seric fprintf(stderr, "Sccs: cannot execute "); 111148Seric perror(cmd->sccspath); 112148Seric exit(EX_UNAVAILABLE); 113148Seric } 114148Seric 115148Seric 116148Seric char * 117148Seric makefile(name) 118148Seric char *name; 119148Seric { 120148Seric register char *p; 121148Seric register char c; 122148Seric char buf[512]; 123148Seric struct stat stbuf; 124148Seric extern char *malloc(); 125148Seric 126148Seric /* 127148Seric ** See if this filename should be used as-is. 128148Seric ** There are three conditions where this can occur. 129148Seric ** 1. The name already begins with "s.". 130148Seric ** 2. The name has a "/" in it somewhere. 131148Seric ** 3. The name references a directory. 132148Seric */ 133148Seric 134148Seric if (strncmp(name, "s.", 2) == 0) 135148Seric return (name); 136148Seric for (p = name; (c = *p) != '\0'; p++) 137148Seric { 138148Seric if (c == '/') 139148Seric return (name); 140148Seric } 141148Seric if (stat(name, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) == S_IFDIR) 142148Seric return (name); 143148Seric 144148Seric /* 145148Seric ** Prepend the path of the sccs file. 146148Seric */ 147148Seric 148148Seric strcpy(buf, SccsPath); 149148Seric strcat(buf, name); 150148Seric p = malloc(strlen(buf) + 1); 151148Seric if (p == NULL) 152148Seric { 153148Seric perror("Sccs: no mem"); 154148Seric exit(EX_OSERR); 155148Seric } 156148Seric strcpy(p, buf); 157148Seric return (p); 158148Seric } 159148Seric 160