admin.c revision 17721
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 19static Dtype admin_dirproc PROTO((char *dir, char *repos, char *update_dir)); 20static int admin_fileproc PROTO((struct file_info *finfo)); 21 22static const char *const admin_usage[] = 23{ 24 "Usage: %s %s rcs-options files...\n", 25 NULL 26}; 27 28static int ac; 29static char **av; 30 31int 32admin (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 */ 115static int 116admin_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 */ 159static Dtype 160admin_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} 169