/* * Copyright (c) 1992, Brian Berliner and Jeff Polk * Copyright (c) 1989-1992, Brian Berliner * * You may distribute under the terms of the GNU General Public License * as specified in the README file that comes with the CVS 1.3 kit. */ #include "cvs.h" #include "rcvs.h" #include "patchlevel.h" static struct cmd *cm; #if __STDC__ int rcvs_add (int argc, char **argv); int rcvs_checkout (int argc, char **argv); int rcvs_export (int argc, char **argv); int rcvs_history (int argc, char **argv); int rcvs_import (int argc, char **argv); int rcvs_need_folder (int argc, char **argv); int rcvs_rdiff (int argc, char **argv); int rcvs_remove (int argc, char **argv); int rcvs_rtag (int argc, char **argv); int rcvs_tag (int argc, char **argv); int rcvs_do_folder (int argc, char **argv); char *rcvs_get_repos (char *dir, char **Id, char **Repository); #else int rcvs_add (); int rcvs_checkout (); int rcvs_export (); int rcvs_history (); int rcvs_import (); int rcvs_need_folder (); int rcvs_rdiff (); int rcvs_remove (); int rcvs_rtag (); int rcvs_tag (); int rcvs_do_folder (); char *rcvs_get_repos (); #endif /* __STDC__ */ struct cmd { char *fullname; char *nick1; char *nick2; int (*func) (); }; static char msg1[] = "clone ----> folder"; static char msg2[] = "clone ----> stdout"; static char msg3[] = "clone <---- folder"; static char msg4[] = "clone <---- tag"; static char msg5[] = "clone <---- changes"; static char msg6[] = "clone <---- changes"; static char msg7[] = "cvsroot ----> stdout"; static char msg8[] = "./CVS <---- changes"; static char msg9[] = "cvsroot <---- tag"; /* struct to describe the behavior of a command with following fields: * * fullname: name of command * sync_name: name of command to use for sync * msg: message to be printed * func: which function to be called * phases: specify phases [1-3]. 1= forward sync 2= local 3= back sync * internal usage: 8= set read-lock 9= set phase3 lock * need_repos: need a clone repository e.g need_repos=0 for 'history' * add_hist: does it change history file? */ struct CMD CMDS [] = { { "add", "add", msg5, rcvs_add, "123", 1, 1 }, { "add_file", "add", msg8, rcvs_add, "128", 1, 1 }, { "admin", "checkout", msg5, rcvs_need_folder, "123", 1, 1 }, { "checkout", "checkout", msg1, rcvs_checkout, "128", 1, 1 }, { "commit", "commit", msg3, rcvs_need_folder, "123", 1, 1 }, { "diff", "checkout", msg2, rcvs_need_folder, "128", 1, 0 }, { "export", "checkout", msg1, rcvs_export, "128", 1, 1 }, { "history", "history", msg7, rcvs_history, "1", 0, 0 }, { "import", "import", msg3, rcvs_import, "123", 1, 1 }, { "log", "checkout", msg2, rcvs_need_folder, "128", 1, 0 }, { "rdiff", "rdiff", msg2, rcvs_rdiff, "1", 0, 0 }, { "release", "checkout", msg8, rcvs_do_folder, "2", 1, 1 }, { "remove", "remove", msg8, rcvs_remove, "128", 0, 1 }, { "rtag", "rtag", msg9, rcvs_rtag, "18", 0, 0 }, { "status", "checkout", msg2, rcvs_do_folder, "128", 1, 0 }, { "tag", "checkout", msg4, rcvs_tag, "123", 1, 1 }, { "update", "checkout", msg1, rcvs_need_folder, "128", 1, 1 }, { NULL, NULL, NULL, NULL, 0, 0 }, }; /* rcvs: find all existing folders */ int rcvs_Find_folder (argc, argv, cmds) int argc; char *argv[]; struct cmd *cmds; { struct CMD *CM; char *CP = argv[0]; char *cp = NULL; int err = 0; char repository[PATH_MAX]; char dir[PATH_MAX]; char *Repository; command_name = argv[0]; err = rcvs_eval_command (argc, argv, cmds); if (err) return (err); /* call cvs command to parse command options */ rcvs_parse_opt = TRUE; err = (*(cm->func)) (argc, argv); rcvs_parse_opt = FALSE; argc -= rcvs_cmd_optind; argv += rcvs_cmd_optind; for (CM = CMDS; CM->fullname; CM++) if (!strcmp (cm->fullname, CM->fullname)) break; rcvs_CM = CM; err = (*(CM->func)) (argc, argv); return (err); } /* rcvs: collect information for commands that needs folder */ int rcvs_need_folder (argc, argv) int argc; char *argv[]; { int err = 0; err = rcvs_do_folder (argc, argv); if (err) error (1, 0, "no legitimate folder found"); return (0); } /* rcvs: put command options into list */ int rcvs_put_options (argc, argv, ID) int argc; char *argv[]; char *ID; { register int i; /* this routine only serves history/rdiff/rtag commands */ if (strcmp(cm->fullname,"history") && strcmp(cm->fullname,"rdiff") && strcmp(cm->fullname,"rtag")) return(0); argv -= rcvs_cmd_optind; if (rcvs_cmd_optind > 0) for (i=1; i 0, some directory or files are specified */ else { for (i=0; ineed_repos) error(1, 0, "rcvs_do_folder: %s is not a CVS folder", argv[0]); else { rcvs_put_options (argc, argv, rcvs_ID); rcvs_addlist(&rcvs_dirlist,rcvs_ID,argv[i], argv[i]); found_folder = TRUE; if (rcvs_ID != NULL && index (rcvs_ID, ':') != NULL) rcvs_native_RCVS = TRUE; } } /* * file or typo, * we'll assume it exists on master repository. */ else { char *fn; (void) strcpy (dir, argv[i]); fn = rindex (dir, '/'); if (fn != NULL) *fn++ = '\0'; else { fn = argv[i]; (void) strcpy (dir, "."); } if (fn == NULL) error(1, 0, "rcvs_do_folder #2: fn = null"); sprintf (repository, "%s/%s", dir, CVSADM_REP); if (isreadable ( repository )) { char *file; char *Repository; repos = rcvs_get_repos (dir, &ID, &Repository); sprintf (repository, "%s/%s", repos, fn); file = xstrdup (repository); rcvs_put_options (argc, argv, ID); rcvs_addlist (&rcvs_dirlist, ID,argv[i],file); found_folder = TRUE; } else { if (rcvs_ID != NULL && index (rcvs_ID, ':') != NULL) rcvs_native_RCVS = TRUE; rcvs_put_options (argc, argv, rcvs_ID); rcvs_addlist(&rcvs_dirlist,rcvs_ID,argv[i], argv[i]); } } if (!found_folder) err = 1; } } return (err); } /* rcvs: set some flags according to the command */ int rcvs_eval_command (argc, argv, cmds) int argc; char *argv[]; struct cmd *cmds; { char *CP = argv[0]; /* translate command into fullname */ for (cm = cmds; cm->fullname; cm++) { if (cm->nick1 && !strcmp (CP, cm->nick1)) break; if (cm->nick2 && !strcmp (CP, cm->nick2)) break; if (!strcmp (CP, cm->fullname)) break; } if (!cm->fullname) { error (0, 0, "rcvs_eval_command: bad command '%s'", argv[0]); rcvs_native_RCVS = FALSE; return (1); } return (0); } /* rcvs: print out error */ int rcvs_local_folder_error ( dir, repository, cvsroot) char *dir; char *repository; char *cvsroot; { if (cvsroot != NULL && index (cvsroot,':') == NULL) fprintf(stderr, "local formatted "); else fprintf(stderr, "remote formatted "); fprintf (stderr, "%s does not match local folder '%s'\n", rcvs_Id, dir); error (1, 0, "%s = %s", CVSADM_REP, repository); return (0); } /* rcvs: print out error */ int rcvs_remote_folder_error ( dir, repository, cvsroot) char *dir; char *repository; char *cvsroot; { if (cvsroot != NULL && index (cvsroot,':') == NULL) fprintf(stderr, "local formatted "); else fprintf(stderr, "remote formatted "); fprintf (stderr, "%s does not match remote folder '%s'\n", rcvs_Id, dir); error (1, 0, "%s = %s", RCVSADM_REMOTE, repository); return (0); } /* rcvs: compare existing folder with current CVSROOT */ rcvs_compare_folder(dir, ID, Repository) char *dir; char *ID; char *Repository; { char *Command_Name; char *command; Command_Name = command_name; command = xstrdup ("rcvs_compare_folder"); command_name = command; if (ID == NULL || Repository == NULL) { error (0, 0, "rcvs_compare_folder: bug #1, ID=%s, Repository=%s", ID, Repository); return (0); } /* check local folder */ if ( index (ID, ':') == NULL) { if ( rcvs_ID != NULL && index (rcvs_ID, ':') != NULL ) (void) rcvs_local_folder_error (dir, ID, rcvs_ID); if (Repository != NULL && rcvs_ID != NULL && (strncmp (Repository, rcvs_ID, strlen (rcvs_ID)) != 0)) (void) rcvs_local_folder_error (dir, Repository, rcvs_ID); } /* check remote folder */ else { if ( index (rcvs_ID, ':') == NULL ) (void) rcvs_remote_folder_error (dir, ID, rcvs_ID); if ( (ID != NULL) && (rcvs_ID != NULL) && (strcmp (ID, rcvs_ID) != 0) ) (void) rcvs_remote_folder_error (dir, ID, rcvs_ID); } free (command); command_name = Command_Name; return (0); } /* rcvs: check existing folders for 'add' */ int rcvs_add (argc, argv) int argc; char *argv[]; { char tmp[PATH_MAX]; char repository[PATH_MAX]; char curdir[PATH_MAX]; char *Repository; char *repos; char *ID; register int i; if (argc <= 0) return(1); /* return if this is not a folder */ sprintf (repository, "./%s", CVSADM_REP); if (!isreadable ( repository )) return (0); /* return if this is not a remote folder */ (void) strcpy (curdir, "."); repos = rcvs_get_repos (curdir, &ID, &Repository); if (!rcvs_native_RCVS) return (0); /* walk the arg list adding files/dirs */ for (i=0; i %s\n", tmp); } (void) system (tmp); } sprintf (repository, "%s/%s", repos, argv[i]); rcvs_addlist(&rcvs_dirlist, ID, argv[i], repository); found_folder = TRUE; } else /* add file */ { struct CMD *CM; if (!isfile (argv[i])) error( 1, 0, "nothing known about %s", argv[i]); for (CM = CMDS; CM->fullname; CM++) if (!strcmp ("add_file", CM->fullname)) break; rcvs_CM = CM; { char *rcvsuser; char *rcvshost; char *rcvsroot; char *rcvsdir; char *cvsroot; (void) rcvs_Parse_ID (ID, &rcvsuser, &rcvshost, &rcvsroot,&rcvsdir, &cvsroot); sprintf (tmp,"%s/%s", rcvsdir, repos); if (trace) fprintf (stderr, "-> rcvs_add: mkdir %s\n", tmp); if (!isdir (tmp)) if ( mkdir ( tmp, 0777) ) { command_name = xstrdup ("rcvs_add"); error (1, 0, "fail to mkdir %s", tmp); } } sprintf (tmp,"%s/%s", repos, argv[i]); rcvs_addlist (&rcvs_dirlist, ID, argv[i], tmp); found_folder = TRUE; } if (!found_folder) error (1, 0, "'%s' not found", argv[i]); } return (0); } int rcvs_checkout (argc, argv) int argc; char *argv[]; { register int i; char repository[PATH_MAX]; char *Repository; char *cp; /* check all the folders */ { char *repos; char *ID; /*if (CVSroot == NULL) error (1, 0, "rcvs_checkout: CVSROOT not specified");*/ { char dir[PATH_MAX]; for (i=0; i 0) { for (i=1; i %s", id, ID); } } else id = Id = ID; } else id = Id; } } } argv += rcvs_cmd_optind; rcvs_put_options (argc, argv, Id); /* put file names into stack if any */ for (i=0; i 2) { { char *CurDir; CurDir = xmalloc (PATH_MAX); (void) getwd (CurDir); fprintf(stderr, "import from '%s'\n", CurDir); } /* cleanup clone */ { char tmp[PATH_MAX]; if ((rcvs_Popt_phases == NULL) || (rcvs_Popt_phases != NULL) && (index(rcvs_Popt_phases,'2') != NULL)) { char *rcvsuser; char *rcvshost; char *rcvsroot; char *rcvsdir; char *cvsroot; if (rcvs_ID != NULL && index (rcvs_ID, ':') != NULL) { (void) rcvs_Parse_ID (rcvs_ID, &rcvsuser, &rcvshost, &rcvsroot,&rcvsdir, &cvsroot); sprintf (tmp,"rm -r -f %s/%s", rcvsdir, argv[0]); if (trace) { command_name = xstrdup ("rcvs_import"); fprintf (stderr, "-> %s\n", tmp); } (void) system (tmp); } } } rcvs_addlist (&rcvs_dirlist, rcvs_ID, argv[0], argv[0]); for (i=1; i 0) { rcvs_cmd_optind += 1; argc -= 1; argv += 1; (void) rcvs_do_folder (argc, argv); } return (0); }