]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/cvs/src/admin.c
Import of slightly trimmed cvs-1.8 distribution. Generated files
[FreeBSD/FreeBSD.git] / contrib / cvs / src / admin.c
1 /*
2  * Copyright (c) 1992, Brian Berliner and Jeff Polk
3  * Copyright (c) 1989-1992, Brian Berliner
4  * 
5  * You may distribute under the terms of the GNU General Public License as
6  * specified in the README file that comes with the CVS 1.4 kit.
7  * 
8  * Administration
9  * 
10  * For now, this is basically a front end for rcs.  All options are passed
11  * directly on.
12  */
13
14 #include "cvs.h"
15 #ifdef CVS_ADMIN_GROUP
16 #include <grp.h>
17 #endif
18
19 static Dtype admin_dirproc PROTO((char *dir, char *repos, char *update_dir));
20 static int admin_fileproc PROTO((struct file_info *finfo));
21
22 static const char *const admin_usage[] =
23 {
24     "Usage: %s %s rcs-options files...\n",
25     NULL
26 };
27
28 static int ac;
29 static char **av;
30
31 int
32 admin (argc, argv)
33     int argc;
34     char **argv;
35 {
36     int err;
37 #ifdef CVS_ADMIN_GROUP
38     struct group *grp;
39 #endif
40     if (argc <= 1)
41         usage (admin_usage);
42
43 #ifdef CVS_ADMIN_GROUP
44     grp = getgrnam(CVS_ADMIN_GROUP);
45      /* skip usage right check if group CVS_ADMIN_GROUP does not exist */
46     if (grp != NULL)
47     {
48         char *me = getcaller();
49         char **grnam = grp->gr_mem;
50         int denied = 1;
51         
52         while (*grnam)
53         {
54             if (strcmp(*grnam, me) == 0) 
55             {
56                 denied = 0;
57                 break;
58             }
59             grnam++;
60         }
61
62         if (denied)
63             error (1, 0, "usage is restricted to members of the group %s",
64                    CVS_ADMIN_GROUP);
65     }
66 #endif
67
68     wrap_setup ();
69
70     /* skip all optional arguments to see if we have any file names */
71     for (ac = 1; ac < argc; ac++)
72         if (argv[ac][0] != '-')
73             break;
74     argc -= ac;
75     av = argv + 1;
76     argv += ac;
77     ac--;
78     if (ac == 0 || argc == 0)
79         usage (admin_usage);
80
81 #ifdef CLIENT_SUPPORT
82     if (client_active)
83     {
84         int i;
85
86         /* We're the client side.  Fire up the remote server.  */
87         start_server ();
88         
89         ign_setup ();
90
91         for (i = 0; i <= ac; ++i)       /* XXX send -ko too with i = 0 */
92             send_arg (av[i]);
93
94         send_file_names (argc, argv, SEND_EXPAND_WILD);
95         /* FIXME:  We shouldn't have to send current files, but I'm not sure
96            whether it works.  So send the files --
97            it's slower but it works.  */
98         send_files (argc, argv, 0, 0);
99         send_to_server ("admin\012", 0);
100         return get_responses_and_close ();
101     }
102 #endif /* CLIENT_SUPPORT */
103
104     /* start the recursion processor */
105     err = start_recursion (admin_fileproc, (FILESDONEPROC) NULL, admin_dirproc,
106                            (DIRLEAVEPROC) NULL, argc, argv, 0,
107                            W_LOCAL, 0, 1, (char *) NULL, 1, 0);
108     return (err);
109 }
110
111 /*
112  * Called to run "rcs" on a particular file.
113  */
114 /* ARGSUSED */
115 static int
116 admin_fileproc (finfo)
117     struct file_info *finfo;
118 {
119     Vers_TS *vers;
120     char *version;
121     char **argv;
122     int argc;
123     int retcode = 0;
124     int status = 0;
125
126     vers = Version_TS (finfo->repository, (char *) NULL, (char *) NULL, (char *) NULL,
127                        finfo->file, 0, 0, finfo->entries, finfo->rcs);
128
129     version = vers->vn_user;
130     if (version == NULL)
131         goto exitfunc;
132     else if (strcmp (version, "0") == 0)
133     {
134         error (0, 0, "cannot admin newly added file `%s'", finfo->file);
135         goto exitfunc;
136     }
137
138     run_setup ("%s%s -x,v/", Rcsbin, RCS);
139     for (argc = ac, argv = av; argc; argc--, argv++)
140         run_arg (*argv);
141     run_arg (vers->srcfile->path);
142     if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
143     {
144         if (!quiet)
145             error (0, retcode == -1 ? errno : 0,
146                    "%s failed for `%s'", RCS, finfo->file);
147         status = 1;
148         goto exitfunc;
149     }
150   exitfunc:
151     freevers_ts (&vers);
152     return status;
153 }
154
155 /*
156  * Print a warm fuzzy message
157  */
158 /* ARGSUSED */
159 static Dtype
160 admin_dirproc (dir, repos, update_dir)
161     char *dir;
162     char *repos;
163     char *update_dir;
164 {
165     if (!quiet)
166         error (0, 0, "Administrating %s", update_dir);
167     return (R_PROCESS);
168 }