date and time created 80/05/18 20:05:58 by bill
[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
833a2471 6static char SccsId[] = "@(#)sccs.c 1.5 delta %G% 11:32:24 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
EA
37char *SccsPath = "SCCS"; /* pathname of SCCS files */
38bool IsAdmin; /* if set, this person is an administrator */
39bool RealUser; /* if set, running as real user */
1cc2dcec
EA
40
41main(argc, argv)
42 int argc;
43 char **argv;
44{
45 register char *p;
46 register char **av;
47 char *newargv[1000];
48 extern char *makefile();
49 register struct sccsprog *cmd;
2a0234bf
EA
50 char buf[200];
51 int uid;
52 auto int xuid;
53 register FILE *fp;
1cc2dcec
EA
54
55 /*
56 ** Detect and decode flags intended for this program.
57 */
58
59 while (--argc > 0)
60 {
61 p = *++argv;
62 if (*p != '-')
63 break;
64 switch (*++p)
65 {
66 case 'r': /* run as real user */
67 setuid(getuid());
2a0234bf 68 RealUser++;
1cc2dcec
EA
69 break;
70
71 case 'p': /* path of sccs files */
72 SccsPath = ++p;
73 break;
74
75 default:
76 fprintf(stderr, "Sccs: unknown option -%s\n", p);
77 break;
78 }
79 }
833a2471
EA
80 if (SccsPath[0] == '\0')
81 SccsPath = ".";
1cc2dcec 82
2a0234bf
EA
83 /*
84 ** See if this user is an administrator.
85 */
86
87 uid = getuid();
88# ifdef V6
89 uid &= 0377;
90# endif V6
91 strcpy(buf, SccsPath);
92 strcat(buf, "/ADMINFILE");
93 fp = fopen(buf, "r");
94 if (fp != NULL)
95 {
96 while (fgets(buf, sizeof buf, fp) != NULL)
97 {
98 if (buf[0] == 'A')
99 {
100 if (sscanf(&buf[1], "%d", &xuid) > 0 &&
101 xuid == uid)
102 IsAdmin++;
103 }
104 }
105 fclose(fp);
106 }
833a2471
EA
107 else
108 {
109 /* no ADMINFILE -- take some defaults */
110 IsAdmin++;
111 }
2a0234bf 112
1cc2dcec
EA
113 /*
114 ** Look up command.
115 ** At this point, p and argv point to the command name.
116 */
117
118 for (cmd = SccsProg; cmd->sccsname != NULL; cmd++)
119 {
120 if (strcmp(cmd->sccsname, p) == 0)
121 break;
122 }
123 if (cmd->sccsname == NULL)
124 {
125 fprintf(stderr, "Sccs: Unknown command \"%s\"\n", p);
126 exit(EX_USAGE);
127 }
128
2a0234bf
EA
129 /*
130 ** Set protection as appropriate.
131 */
132
133 if (bitset(F_PROT, cmd->sccsflags) && !IsAdmin && !RealUser)
134 {
135 fprintf(stderr, "Sccs: not authorized to use %s\n", p);
136 exit(EX_USAGE);
137 }
138
1cc2dcec
EA
139 /*
140 ** Build new argument vector.
1cc2dcec
EA
141 */
142
1cc2dcec
EA
143 av = newargv;
144 *av++ = p;
145
1859e236
EA
146 /* copy program filename arguments and flags */
147 while (--argc > 0)
1cc2dcec 148 {
1859e236 149 p = *++argv;
2a0234bf 150 if (!bitset(F_NOSDOT, cmd->sccsflags) && *p != '-')
1859e236 151 *av++ = makefile(p);
1cc2dcec 152 else
1859e236 153 *av++ = p;
1cc2dcec
EA
154 }
155
156 /* terminate argument vector */
157 *av = NULL;
158
159 /*
160 ** Call real SCCS program.
161 */
162
163 execv(cmd->sccspath, newargv);
164 fprintf(stderr, "Sccs: cannot execute ");
165 perror(cmd->sccspath);
166 exit(EX_UNAVAILABLE);
167}
168
169
170char *
171makefile(name)
172 char *name;
173{
174 register char *p;
175 register char c;
176 char buf[512];
177 struct stat stbuf;
178 extern char *malloc();
179
180 /*
181 ** See if this filename should be used as-is.
182 ** There are three conditions where this can occur.
183 ** 1. The name already begins with "s.".
184 ** 2. The name has a "/" in it somewhere.
185 ** 3. The name references a directory.
186 */
187
188 if (strncmp(name, "s.", 2) == 0)
189 return (name);
190 for (p = name; (c = *p) != '\0'; p++)
191 {
192 if (c == '/')
193 return (name);
194 }
195 if (stat(name, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) == S_IFDIR)
196 return (name);
197
198 /*
199 ** Prepend the path of the sccs file.
200 */
201
202 strcpy(buf, SccsPath);
2a0234bf 203 strcat(buf, "/s.");
1cc2dcec
EA
204 strcat(buf, name);
205 p = malloc(strlen(buf) + 1);
206 if (p == NULL)
207 {
208 perror("Sccs: no mem");
209 exit(EX_OSERR);
210 }
211 strcpy(p, buf);
212 return (p);
213}
214