drop ADMINFILE junk & suid to sccs
[unix-history] / usr / src / usr.bin / sccs / sccs.c
CommitLineData
1cc2dcec
EA
1# include <stdio.h>
2# include <sys/types.h>
3# include <sys/stat.h>
4# include <sysexits.h>
5
8ec6d6d9 6static char SccsId[] = "@(#)sccs.c 1.6 delta %G% 19:12:04 get %H% %T%";
2a0234bf
EA
7
8# define bitset(bit, word) ((bit) & (word))
9
10typedef char bool;
81dc6403 11
1cc2dcec
EA
12struct sccsprog
13{
14 char *sccsname; /* name of SCCS routine */
15 short sccsflags; /* see below */
16 char *sccspath; /* pathname of binary implementing */
17};
18
2a0234bf 19/* bits for sccsflags */
1cc2dcec 20# define F_NOSDOT 0001 /* no s. on front of args */
2a0234bf 21# define F_PROT 0002 /* protected (e.g., admin) */
1cc2dcec
EA
22
23struct sccsprog SccsProg[] =
24{
2a0234bf 25 "admin", F_PROT, "/usr/sccs/admin",
1859e236 26 "chghist", 0, "/usr/sccs/rmdel",
1cc2dcec
EA
27 "comb", 0, "/usr/sccs/comb",
28 "delta", 0, "/usr/sccs/delta",
29 "get", 0, "/usr/sccs/get",
1859e236 30 "help", F_NOSDOT, "/usr/sccs/help",
1cc2dcec 31 "prt", 0, "/usr/sccs/prt",
2a0234bf 32 "rmdel", F_PROT, "/usr/sccs/rmdel",
1cc2dcec
EA
33 "what", F_NOSDOT, "/usr/sccs/what",
34 NULL, 0, NULL
35};
36
2a0234bf 37char *SccsPath = "SCCS"; /* pathname of SCCS files */
2a0234bf 38bool RealUser; /* if set, running as real user */
1cc2dcec
EA
39
40main(argc, argv)
41 int argc;
42 char **argv;
43{
44 register char *p;
45 register char **av;
46 char *newargv[1000];
47 extern char *makefile();
48 register struct sccsprog *cmd;
2a0234bf 49 char buf[200];
2a0234bf 50 register FILE *fp;
1cc2dcec
EA
51
52 /*
53 ** Detect and decode flags intended for this program.
54 */
55
56 while (--argc > 0)
57 {
58 p = *++argv;
59 if (*p != '-')
60 break;
61 switch (*++p)
62 {
63 case 'r': /* run as real user */
64 setuid(getuid());
2a0234bf 65 RealUser++;
1cc2dcec
EA
66 break;
67
68 case 'p': /* path of sccs files */
69 SccsPath = ++p;
70 break;
71
72 default:
73 fprintf(stderr, "Sccs: unknown option -%s\n", p);
74 break;
75 }
76 }
833a2471
EA
77 if (SccsPath[0] == '\0')
78 SccsPath = ".";
1cc2dcec 79
2a0234bf
EA
80 /*
81 ** See if this user is an administrator.
82 */
83
1cc2dcec
EA
84 /*
85 ** Look up command.
86 ** At this point, p and argv point to the command name.
87 */
88
89 for (cmd = SccsProg; cmd->sccsname != NULL; cmd++)
90 {
91 if (strcmp(cmd->sccsname, p) == 0)
92 break;
93 }
94 if (cmd->sccsname == NULL)
95 {
96 fprintf(stderr, "Sccs: Unknown command \"%s\"\n", p);
97 exit(EX_USAGE);
98 }
99
2a0234bf
EA
100 /*
101 ** Set protection as appropriate.
102 */
103
8ec6d6d9
EA
104 if (bitset(F_PROT, cmd->sccsflags))
105 setuid(getuid());
2a0234bf 106
1cc2dcec
EA
107 /*
108 ** Build new argument vector.
1cc2dcec
EA
109 */
110
1cc2dcec
EA
111 av = newargv;
112 *av++ = p;
113
1859e236
EA
114 /* copy program filename arguments and flags */
115 while (--argc > 0)
1cc2dcec 116 {
1859e236 117 p = *++argv;
2a0234bf 118 if (!bitset(F_NOSDOT, cmd->sccsflags) && *p != '-')
1859e236 119 *av++ = makefile(p);
1cc2dcec 120 else
1859e236 121 *av++ = p;
1cc2dcec
EA
122 }
123
124 /* terminate argument vector */
125 *av = NULL;
126
127 /*
128 ** Call real SCCS program.
129 */
130
131 execv(cmd->sccspath, newargv);
132 fprintf(stderr, "Sccs: cannot execute ");
133 perror(cmd->sccspath);
134 exit(EX_UNAVAILABLE);
135}
136
137
138char *
139makefile(name)
140 char *name;
141{
142 register char *p;
143 register char c;
144 char buf[512];
145 struct stat stbuf;
146 extern char *malloc();
147
148 /*
149 ** See if this filename should be used as-is.
150 ** There are three conditions where this can occur.
151 ** 1. The name already begins with "s.".
152 ** 2. The name has a "/" in it somewhere.
153 ** 3. The name references a directory.
154 */
155
156 if (strncmp(name, "s.", 2) == 0)
157 return (name);
158 for (p = name; (c = *p) != '\0'; p++)
159 {
160 if (c == '/')
161 return (name);
162 }
163 if (stat(name, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) == S_IFDIR)
164 return (name);
165
166 /*
167 ** Prepend the path of the sccs file.
168 */
169
170 strcpy(buf, SccsPath);
2a0234bf 171 strcat(buf, "/s.");
1cc2dcec
EA
172 strcat(buf, name);
173 p = malloc(strlen(buf) + 1);
174 if (p == NULL)
175 {
176 perror("Sccs: no mem");
177 exit(EX_OSERR);
178 }
179 strcpy(p, buf);
180 return (p);
181}
182