create_adm.c revision 54427
1163953Srrs/* 2185694Srrs * Copyright (c) 1992, Brian Berliner and Jeff Polk 3235828Stuexen * Copyright (c) 1989-1992, Brian Berliner 4235828Stuexen * 5163953Srrs * You may distribute under the terms of the GNU General Public License as 6163953Srrs * specified in the README file that comes with the CVS source distribution. 7163953Srrs * 8163953Srrs * Create Administration. 9163953Srrs * 10228653Stuexen * Creates a CVS administration directory based on the argument repository; the 11163953Srrs * "Entries" file is prefilled from the "initrecord" argument. 12163953Srrs */ 13163953Srrs 14228653Stuexen#include "cvs.h" 15163953Srrs 16163953Srrs/* update_dir includes dir as its last component. 17163953Srrs 18163953Srrs Return value is 0 for success, or 1 if we printed a warning message. 19163953Srrs Note that many errors are still fatal; particularly for unlikely errors 20163953Srrs a fatal error is probably better than a warning which might be missed 21163953Srrs or after which CVS might do something non-useful. If WARN is zero, then 22163953Srrs don't print warnings; all errors are fatal then. */ 23163953Srrs 24163953Srrsint 25163953SrrsCreate_Admin (dir, update_dir, repository, tag, date, nonbranch, warn) 26163953Srrs char *dir; 27163953Srrs char *update_dir; 28163953Srrs char *repository; 29163953Srrs char *tag; 30163953Srrs char *date; 31163953Srrs int nonbranch; 32163953Srrs int warn; 33163953Srrs{ 34163953Srrs FILE *fout; 35235828Stuexen char *cp; 36166086Srrs char *reposcopy; 37163953Srrs char *tmp; 38163953Srrs 39163953Srrs if (trace) 40163953Srrs { 41238475Stuexen fprintf (stderr, "%s-> Create_Admin (%s, %s, %s, %s, %s, %d, %d)\n", 42283699Stuexen CLIENT_SERVER_STR, 43167695Srrs dir, update_dir, repository, tag ? tag : "", 44167598Srrs date ? date : "", nonbranch, warn); 45163953Srrs } 46163953Srrs 47163953Srrs if (noexec) 48163953Srrs return 0; 49163953Srrs 50163953Srrs tmp = xmalloc (strlen (dir) + 100); 51163953Srrs if (dir != NULL) 52170091Srrs (void) sprintf (tmp, "%s/%s", dir, CVSADM); 53185694Srrs else 54164085Srrs (void) strcpy (tmp, CVSADM); 55163953Srrs if (isfile (tmp)) 56163953Srrs error (1, 0, "there is a version in %s already", update_dir); 57217611Stuexen 58217760Stuexen if (CVS_MKDIR (tmp, 0777) < 0) 59170091Srrs { 60163953Srrs /* We want to print out the entire update_dir, since a lot of 61163953Srrs our code calls this function with dir == "." or dir == 62163953Srrs NULL. I hope that gives enough information in cases like 63163953Srrs absolute pathnames; printing out xgetwd or something would 64163953Srrs be way too verbose in the common cases. */ 65179783Srrs 66179783Srrs if (warn) 67163953Srrs { 68179783Srrs /* The reason that this is a warning, rather than silently 69163953Srrs just skipping creating the directory, is that we don't want 70163953Srrs CVS's behavior to vary subtly based on factors (like directory 71163953Srrs permissions) which are not made clear to the user. With 72163953Srrs the warning at least we let them know what is going on. */ 73163953Srrs error (0, errno, "warning: cannot make directory %s in %s", 74179783Srrs CVSADM, update_dir); 75170056Srrs free (tmp); 76163953Srrs return 1; 77163953Srrs } 78163953Srrs else 79163953Srrs error (1, errno, "cannot make directory %s in %s", 80163953Srrs CVSADM, update_dir); 81179783Srrs } 82179783Srrs 83179783Srrs /* record the current cvs root for later use */ 84179783Srrs 85179783Srrs Create_Root (dir, CVSroot_original); 86179783Srrs if (dir != NULL) 87179783Srrs (void) sprintf (tmp, "%s/%s", dir, CVSADM_REP); 88179783Srrs else 89179783Srrs (void) strcpy (tmp, CVSADM_REP); 90163953Srrs fout = CVS_FOPEN (tmp, "w+"); 91163953Srrs if (fout == NULL) 92179783Srrs { 93179783Srrs if (update_dir[0] == '\0') 94179783Srrs error (1, errno, "cannot open %s", tmp); 95179783Srrs else 96179783Srrs error (1, errno, "cannot open %s/%s", update_dir, CVSADM_REP); 97163953Srrs } 98166023Srrs reposcopy = xstrdup (repository); 99163953Srrs Sanitize_Repository_Name (reposcopy); 100179157Srrs 101228653Stuexen /* The top level of the repository is a special case -- we need to 102163953Srrs write it with an extra dot at the end. This trailing `.' stuff 103163953Srrs rubs me the wrong way -- on the other hand, I don't want to 104197257Stuexen spend the time making sure all of the code can handle it if we 105163953Srrs don't do it. */ 106163953Srrs 107163953Srrs if (strcmp (reposcopy, CVSroot_directory) == 0) 108163953Srrs { 109197257Stuexen reposcopy = xrealloc (reposcopy, strlen (reposcopy) + 3); 110197257Stuexen strcat (reposcopy, "/."); 111197257Stuexen } 112197257Stuexen 113163953Srrs cp = reposcopy; 114197257Stuexen 115163953Srrs#ifdef RELATIVE_REPOS 116163953Srrs /* 117163953Srrs * If the Repository file is to hold a relative path, try to strip off 118163953Srrs * the leading CVSroot argument. 119197257Stuexen */ 120163953Srrs if (CVSroot_directory != NULL) 121163953Srrs { 122163953Srrs char *path = xmalloc (strlen (CVSroot_directory) + 10); 123163953Srrs 124163953Srrs (void) sprintf (path, "%s/", CVSroot_directory); 125190689Srrs if (strncmp (cp, path, strlen (path)) == 0) 126190689Srrs cp += strlen (path); 127190689Srrs free (path); 128283729Stuexen } 129163953Srrs#endif 130283729Stuexen 131283729Stuexen if (fprintf (fout, "%s\n", cp) < 0) 132283729Stuexen { 133283729Stuexen if (update_dir[0] == '\0') 134283729Stuexen error (1, errno, "write to %s failed", tmp); 135283729Stuexen else 136283729Stuexen error (1, errno, "write to %s/%s failed", update_dir, CVSADM_REP); 137283729Stuexen } 138283729Stuexen if (fclose (fout) == EOF) 139283729Stuexen { 140163953Srrs if (update_dir[0] == '\0') 141163953Srrs error (1, errno, "cannot close %s", tmp); 142163953Srrs else 143163953Srrs error (1, errno, "cannot close %s/%s", update_dir, CVSADM_REP); 144163953Srrs } 145221249Stuexen 146163953Srrs /* now, do the Entries file */ 147163953Srrs if (dir != NULL) 148163953Srrs (void) sprintf (tmp, "%s/%s", dir, CVSADM_ENT); 149163953Srrs else 150163953Srrs (void) strcpy (tmp, CVSADM_ENT); 151163953Srrs fout = CVS_FOPEN (tmp, "w+"); 152163953Srrs if (fout == NULL) 153163953Srrs { 154163953Srrs if (update_dir[0] == '\0') 155163953Srrs error (1, errno, "cannot open %s", tmp); 156163953Srrs else 157163953Srrs error (1, errno, "cannot open %s/%s", update_dir, CVSADM_ENT); 158163953Srrs } 159163953Srrs if (fclose (fout) == EOF) 160169420Srrs { 161163953Srrs if (update_dir[0] == '\0') 162169420Srrs error (1, errno, "cannot close %s", tmp); 163163953Srrs else 164163953Srrs error (1, errno, "cannot close %s/%s", update_dir, CVSADM_ENT); 165163953Srrs } 166163953Srrs 167163953Srrs /* Create a new CVS/Tag file */ 168163953Srrs WriteTag (dir, tag, date, nonbranch, update_dir, repository); 169163953Srrs 170163953Srrs#ifdef SERVER_SUPPORT 171163953Srrs if (server_active) 172163953Srrs { 173163953Srrs server_template (update_dir, repository); 174163953Srrs } 175163953Srrs 176163953Srrs if (trace) 177163953Srrs { 178163953Srrs fprintf (stderr, "%c<- Create_Admin\n", 179163953Srrs (server_active) ? 'S' : ' '); 180163953Srrs } 181163953Srrs#endif 182241913Sglebius 183163953Srrs free (reposcopy); 184171943Srrs free (tmp); 185163953Srrs return 0; 186163953Srrs} 187163953Srrs