admin.c revision 25839
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 ((void *callerdat, char *dir, 20 char *repos, char *update_dir, 21 List *entries)); 22static int admin_fileproc PROTO ((void *callerdat, struct file_info *finfo)); 23 24static const char *const admin_usage[] = 25{ 26 "Usage: %s %s rcs-options files...\n", 27 NULL 28}; 29 30static int ac; 31static char **av; 32 33int 34admin (argc, argv) 35 int argc; 36 char **argv; 37{ 38 int err; 39#ifdef CVS_ADMIN_GROUP 40 struct group *grp; 41 struct group *getgrnam(); 42#endif 43 if (argc <= 1) 44 usage (admin_usage); 45 46#ifdef CVS_ADMIN_GROUP 47 grp = getgrnam(CVS_ADMIN_GROUP); 48 /* skip usage right check if group CVS_ADMIN_GROUP does not exist */ 49 if (grp != NULL) 50 { 51 char *me = getcaller(); 52 char **grnam = grp->gr_mem; 53 int denied = 1; 54 55 while (*grnam) 56 { 57 if (strcmp(*grnam, me) == 0) 58 { 59 denied = 0; 60 break; 61 } 62 grnam++; 63 } 64 65 if (denied) 66 error (1, 0, "usage is restricted to members of the group %s", 67 CVS_ADMIN_GROUP); 68 } 69#endif 70 71 wrap_setup (); 72 73 /* skip all optional arguments to see if we have any file names */ 74 for (ac = 1; ac < argc; ac++) 75 if (argv[ac][0] != '-') 76 break; 77 argc -= ac; 78 av = argv + 1; 79 argv += ac; 80 ac--; 81 82#ifdef CLIENT_SUPPORT 83 if (client_active) 84 { 85 int i; 86 87 /* We're the client side. Fire up the remote server. */ 88 start_server (); 89 90 ign_setup (); 91 92 for (i = 0; i < ac; ++i) /* XXX send -ko too with i = 0 */ 93 send_arg (av[i]); 94 95 send_file_names (argc, argv, SEND_EXPAND_WILD); 96 send_files (argc, argv, 0, 0, SEND_NO_CONTENTS); 97 send_to_server ("admin\012", 0); 98 return get_responses_and_close (); 99 } 100#endif /* CLIENT_SUPPORT */ 101 102 /* start the recursion processor */ 103 err = start_recursion (admin_fileproc, (FILESDONEPROC) NULL, admin_dirproc, 104 (DIRLEAVEPROC) NULL, NULL, argc, argv, 0, 105 W_LOCAL, 0, 1, (char *) NULL, 1); 106 return (err); 107} 108 109/* 110 * Called to run "rcs" on a particular file. 111 */ 112/* ARGSUSED */ 113static int 114admin_fileproc (callerdat, finfo) 115 void *callerdat; 116 struct file_info *finfo; 117{ 118 Vers_TS *vers; 119 char *version; 120 char **argv; 121 int argc; 122 int retcode = 0; 123 int status = 0; 124 125 vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0); 126 127 version = vers->vn_user; 128 if (version == NULL) 129 goto exitfunc; 130 else if (strcmp (version, "0") == 0) 131 { 132 error (0, 0, "cannot admin newly added file `%s'", finfo->file); 133 goto exitfunc; 134 } 135 136 run_setup ("%s%s -x,v/", Rcsbin, RCS); 137 for (argc = ac, argv = av; argc; argc--, argv++) 138 run_arg (*argv); 139 run_arg (vers->srcfile->path); 140 if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0) 141 { 142 if (!quiet) 143 error (0, retcode == -1 ? errno : 0, 144 "%s failed for `%s'", RCS, finfo->file); 145 status = 1; 146 goto exitfunc; 147 } 148 exitfunc: 149 freevers_ts (&vers); 150 return status; 151} 152 153/* 154 * Print a warm fuzzy message 155 */ 156/* ARGSUSED */ 157static Dtype 158admin_dirproc (callerdat, dir, repos, update_dir, entries) 159 void *callerdat; 160 char *dir; 161 char *repos; 162 char *update_dir; 163 List *entries; 164{ 165 if (!quiet) 166 error (0, 0, "Administrating %s", update_dir); 167 return (R_PROCESS); 168} 169