xref: /csrg-svn/usr.bin/sccs/sccs.c (revision 157)
1148Seric # include <stdio.h>
2148Seric # include <sys/types.h>
3148Seric # include <sys/stat.h>
4148Seric # include <sysexits.h>
5148Seric 
6*157Seric static char SccsId[] = "@(#)sccs.c 1.4 delta 05/13/80 11:18:42 get 10/14/12 16:33:33";
7155Seric 
8*157Seric # define bitset(bit, word)	((bit) & (word))
9*157Seric 
10*157Seric typedef char	bool;
11*157Seric 
12148Seric struct sccsprog
13148Seric {
14148Seric 	char	*sccsname;	/* name of SCCS routine */
15148Seric 	short	sccsflags;	/* see below */
16148Seric 	char	*sccspath;	/* pathname of binary implementing */
17148Seric };
18148Seric 
19*157Seric /* bits for sccsflags */
20148Seric # define F_NOSDOT	0001	/* no s. on front of args */
21*157Seric # define F_PROT		0002	/* protected (e.g., admin) */
22148Seric 
23148Seric struct sccsprog SccsProg[] =
24148Seric {
25*157Seric 	"admin",	F_PROT,			"/usr/sccs/admin",
26153Seric 	"chghist",	0,			"/usr/sccs/rmdel",
27148Seric 	"comb",		0,			"/usr/sccs/comb",
28148Seric 	"delta",	0,			"/usr/sccs/delta",
29148Seric 	"get",		0,			"/usr/sccs/get",
30153Seric 	"help",		F_NOSDOT,		"/usr/sccs/help",
31148Seric 	"prt",		0,			"/usr/sccs/prt",
32*157Seric 	"rmdel",	F_PROT,			"/usr/sccs/rmdel",
33148Seric 	"what",		F_NOSDOT,		"/usr/sccs/what",
34148Seric 	NULL,		0,			NULL
35148Seric };
36148Seric 
37*157Seric char	*SccsPath = "SCCS";	/* pathname of SCCS files */
38*157Seric bool	IsAdmin;		/* if set, this person is an administrator */
39*157Seric bool	RealUser;		/* if set, running as real user */
40148Seric 
41148Seric main(argc, argv)
42148Seric 	int argc;
43148Seric 	char **argv;
44148Seric {
45148Seric 	register char *p;
46148Seric 	register char **av;
47148Seric 	char *newargv[1000];
48148Seric 	extern char *makefile();
49148Seric 	register struct sccsprog *cmd;
50*157Seric 	char buf[200];
51*157Seric 	int uid;
52*157Seric 	auto int xuid;
53*157Seric 	register FILE *fp;
54148Seric 
55148Seric 	/*
56148Seric 	**  Detect and decode flags intended for this program.
57148Seric 	*/
58148Seric 
59148Seric 	while (--argc > 0)
60148Seric 	{
61148Seric 		p = *++argv;
62148Seric 		if (*p != '-')
63148Seric 			break;
64148Seric 		switch (*++p)
65148Seric 		{
66148Seric 		  case 'r':		/* run as real user */
67148Seric 			setuid(getuid());
68*157Seric 			RealUser++;
69148Seric 			break;
70148Seric 
71148Seric 		  case 'p':		/* path of sccs files */
72148Seric 			SccsPath = ++p;
73148Seric 			break;
74148Seric 
75148Seric 		  default:
76148Seric 			fprintf(stderr, "Sccs: unknown option -%s\n", p);
77148Seric 			break;
78148Seric 		}
79148Seric 	}
80148Seric 
81148Seric 	/*
82*157Seric 	**  See if this user is an administrator.
83*157Seric 	*/
84*157Seric 
85*157Seric 	uid = getuid();
86*157Seric # ifdef V6
87*157Seric 	uid &= 0377;
88*157Seric # endif V6
89*157Seric 	strcpy(buf, SccsPath);
90*157Seric 	strcat(buf, "/ADMINFILE");
91*157Seric 	fp = fopen(buf, "r");
92*157Seric 	if (fp != NULL)
93*157Seric 	{
94*157Seric 		while (fgets(buf, sizeof buf, fp) != NULL)
95*157Seric 		{
96*157Seric 			if (buf[0] == 'A')
97*157Seric 			{
98*157Seric 				if (sscanf(&buf[1], "%d", &xuid) > 0 &&
99*157Seric 				    xuid == uid)
100*157Seric 					IsAdmin++;
101*157Seric 			}
102*157Seric 		}
103*157Seric 		fclose(fp);
104*157Seric 	}
105*157Seric 
106*157Seric 	/*
107148Seric 	**  Look up command.
108148Seric 	**	At this point, p and argv point to the command name.
109148Seric 	*/
110148Seric 
111148Seric 	for (cmd = SccsProg; cmd->sccsname != NULL; cmd++)
112148Seric 	{
113148Seric 		if (strcmp(cmd->sccsname, p) == 0)
114148Seric 			break;
115148Seric 	}
116148Seric 	if (cmd->sccsname == NULL)
117148Seric 	{
118148Seric 		fprintf(stderr, "Sccs: Unknown command \"%s\"\n", p);
119148Seric 		exit(EX_USAGE);
120148Seric 	}
121148Seric 
122148Seric 	/*
123*157Seric 	**  Set protection as appropriate.
124*157Seric 	*/
125*157Seric 
126*157Seric 	if (bitset(F_PROT, cmd->sccsflags) && !IsAdmin && !RealUser)
127*157Seric 	{
128*157Seric 		fprintf(stderr, "Sccs: not authorized to use %s\n", p);
129*157Seric 		exit(EX_USAGE);
130*157Seric 	}
131*157Seric 
132*157Seric 	/*
133148Seric 	**  Build new argument vector.
134148Seric 	*/
135148Seric 
136148Seric 	av = newargv;
137148Seric 	*av++ = p;
138148Seric 
139153Seric 	/* copy program filename arguments and flags */
140153Seric 	while (--argc > 0)
141148Seric 	{
142153Seric 		p = *++argv;
143*157Seric 		if (!bitset(F_NOSDOT, cmd->sccsflags) && *p != '-')
144153Seric 			*av++ = makefile(p);
145148Seric 		else
146153Seric 			*av++ = p;
147148Seric 	}
148148Seric 
149148Seric 	/* terminate argument vector */
150148Seric 	*av = NULL;
151148Seric 
152148Seric 	/*
153148Seric 	**  Call real SCCS program.
154148Seric 	*/
155148Seric 
156148Seric 	execv(cmd->sccspath, newargv);
157148Seric 	fprintf(stderr, "Sccs: cannot execute ");
158148Seric 	perror(cmd->sccspath);
159148Seric 	exit(EX_UNAVAILABLE);
160148Seric }
161148Seric 
162148Seric 
163148Seric char *
164148Seric makefile(name)
165148Seric 	char *name;
166148Seric {
167148Seric 	register char *p;
168148Seric 	register char c;
169148Seric 	char buf[512];
170148Seric 	struct stat stbuf;
171148Seric 	extern char *malloc();
172148Seric 
173148Seric 	/*
174148Seric 	**  See if this filename should be used as-is.
175148Seric 	**	There are three conditions where this can occur.
176148Seric 	**	1. The name already begins with "s.".
177148Seric 	**	2. The name has a "/" in it somewhere.
178148Seric 	**	3. The name references a directory.
179148Seric 	*/
180148Seric 
181148Seric 	if (strncmp(name, "s.", 2) == 0)
182148Seric 		return (name);
183148Seric 	for (p = name; (c = *p) != '\0'; p++)
184148Seric 	{
185148Seric 		if (c == '/')
186148Seric 			return (name);
187148Seric 	}
188148Seric 	if (stat(name, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) == S_IFDIR)
189148Seric 		return (name);
190148Seric 
191148Seric 	/*
192148Seric 	**  Prepend the path of the sccs file.
193148Seric 	*/
194148Seric 
195148Seric 	strcpy(buf, SccsPath);
196*157Seric 	strcat(buf, "/s.");
197148Seric 	strcat(buf, name);
198148Seric 	p = malloc(strlen(buf) + 1);
199148Seric 	if (p == NULL)
200148Seric 	{
201148Seric 		perror("Sccs: no mem");
202148Seric 		exit(EX_OSERR);
203148Seric 	}
204148Seric 	strcpy(p, buf);
205148Seric 	return (p);
206148Seric }
207148Seric 
208