This is rcvs_folder.c in view mode; [Download] [Up]
/*
* 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
* steps: specify steps [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<rcvs_cmd_optind; i++)
rcvs_addlist (&rcvs_dirlist, ID, argv[i], argv[i]);
argv += rcvs_cmd_optind;
return (0);
}
/* rcvs: find existing folders */
int
rcvs_do_folder (argc, argv)
int argc;
char *argv[];
{
char repository[PATH_MAX];
char dir[PATH_MAX];
char *Repository;
char *repos;
char *ID;
register int i;
int err = 0;
/* no directory is specified, use current directory */
if (argc == 0)
{
/* if CVS found, current directory is a module */
if ( isreadable (CVSADM_REP))
{
repos = rcvs_get_repos (".", &ID, &Repository);
rcvs_put_options (argc, argv, ID);
rcvs_addlist (&rcvs_dirlist, ID, "", repos);
}
/* no module found, search for all folders in current directory */
else
{
List *L;
L = Find_Dirs ((char *) NULL, W_LOCAL);
if ( L != NULL )
rcvs_walklist (argc, argv, "rcvs_do_folder", L, rcvs_add_onedir);
}
}
/* argc > 0, some directory or files are specified */
else
{
for (i=0; i<argc; i++)
{
int found_folder = FALSE;
sprintf (repository, "%s/%s", argv[i], CVSADM_REP);
/* directory */
if (isreadable ( repository))
{
repos = rcvs_get_repos (argv[i], &ID, &Repository);
if (!quiet && ID != NULL && index(ID,':') != NULL &&
CVSrootr_v != NULL && index(ID,':') != NULL &&
strcmp (ID, CVSrootr_v) != 0)
fprintf (stderr, "%s is ignored\n", CVSrootr_n);
rcvs_put_options (argc, argv, ID);
rcvs_addlist(&rcvs_dirlist, ID, argv[i], repos);
found_folder = TRUE;
}
/* if CVS directory doesn't exist, error */
else if ( isdir(argv[i]))
{
if (rcvs_CM->need_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<argc; i++)
{
int found_folder = FALSE;
if (rindex (argv[i], '/'))
error (1, 0,
"cannot add files with '/' in their name; %s not added",argv[i]);
sprintf (repository, "%s/%s", argv[i], CVSADM_REP);
if ( isdir(argv[i])) /* add dir */
{
if ((rcvs_Popt_phases == NULL) ||
(rcvs_Popt_phases != NULL) &&
(index(rcvs_Popt_phases,'2') != NULL))
{
/* CVS already exist, ERROR */
if ( isreadable ( repository))
error(1, 0,"rcvs_add: %s is a CVS folder", argv[0]);
sprintf (tmp,"rm -r -f %s/%s/%s", Repository, repos, argv[0]);
if (trace)
{
command_name = xstrdup ("rcvs_add");
fprintf (stderr, "-> %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<argc; i++)
{
if (rcvs_dopt_where != NULL) /* co -d */
{
if (rcvs_ID != NULL && index (rcvs_ID, ':') != NULL)
rcvs_native_RCVS = TRUE;
rcvs_addlist(&rcvs_dirlist,rcvs_ID,argv[i], argv[i]);
}
else
{
sprintf (repository, "%s/%s", argv[i], CVSADM_REP);
if ( isreadable ( repository ) ) /* directory */
{
repos = rcvs_get_repos (argv[i], &ID, &Repository);
(void) rcvs_compare_folder(argv[i], ID, Repository);
rcvs_addlist (&rcvs_dirlist, rcvs_ID, argv[i], repos);
}
else if (isdir(argv[i])) /* non-CVS folder */
error(1, 0, "rcvs_checkout: a non-CVS directory '%s' exist",
argv[i]);
else /* file or non-exist dir*/
{
if (rcvs_ID != NULL && index (rcvs_ID, ':') != NULL)
rcvs_native_RCVS = TRUE;
rcvs_addlist(&rcvs_dirlist,rcvs_ID,argv[i], argv[i]);
}
}
}
}
}
return (0);
}
int
rcvs_export (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;
{
char dir[PATH_MAX];
for (i=0; i<argc; i++)
{
if (rcvs_dopt_where != NULL) /* export -d */
{
if (rcvs_ID != NULL && index (rcvs_ID, ':') != NULL)
rcvs_native_RCVS = TRUE;
rcvs_addlist(&rcvs_dirlist,rcvs_ID,argv[i], argv[i]);
}
else
{
sprintf (repository, "%s/%s", argv[i], CVSADM_REP);
if ( isreadable ( repository ) ) /* directory */
error (1, 0, "CVS folder '%s' exist", argv[i]);
else if (isdir(argv[i])) /* non-CVS folder */
error(1, 0, "rcvs_export: a non-CVS directory '%s' exist",
argv[i]);
else /* file or non-exist dir */
{
if (rcvs_ID != NULL && index (rcvs_ID, ':') != NULL)
rcvs_native_RCVS = TRUE;
rcvs_addlist(&rcvs_dirlist,rcvs_ID,argv[i], argv[i]);
}
}
}
}
}
return (0);
}
/* rcvs: collect arguments for 'history' */
int
rcvs_history (argc, argv)
int argc;
char *argv[];
{
register int i;
char repository[PATH_MAX];
char *Repository;
char *repos;
char *ID = NULL;
char *Id = NULL;
char *id = NULL; /* ID of folder, all folder must have same ID */
int has_mod = 0;
argv -= rcvs_cmd_optind;
if ( isreadable (CVSADM_REP))
repos = rcvs_get_repos (".", &Id, &Repository);
else
Id=rcvs_ID;
if (rcvs_cmd_optind > 0)
{
for (i=1; i<rcvs_cmd_optind; i++)
{
if ((strcmp(argv[i],"-m") == 0) || (strcmp(argv[i],"-n") == 0))
{
i++;
has_mod++;
sprintf (repository, "%s/%s", argv[i], CVSADM_REP);
if (isreadable ( repository ))
{
repos = rcvs_get_repos (argv[i], &ID, &Repository);
if (id != NULL)
{
if (strcmp(id, ID) != 0)
{
error(0, 0, "RCVS cannot inquire history for folders from different repository");
error(1, 0, "%s <> %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<argc; i++)
rcvs_addlist (&rcvs_dirlist, Id, argv[i], argv[i]);
if (rcvs_ID != NULL && index (rcvs_ID, ':') == NULL)
return (0);
return (0);
}
int
rcvs_import (argc, argv)
int argc;
char *argv[];
{
register int i;
if (rcvs_ID != NULL && index (rcvs_ID, ':') == NULL)
return (0);
rcvs_native_RCVS = TRUE;
if (argc > 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<argc; i++)
rcvs_addlist (&rcvs_dirlist, rcvs_ID, argv[i], "");
}
else
rcvs_addlist (&rcvs_dirlist, rcvs_ID, "", "");
return (0);
}
/* rcvs: collect information for rdiff */
int
rcvs_rdiff (argc, argv)
int argc;
char *argv[];
{
register int i;
if (rcvs_ID != NULL && index (rcvs_ID, ':') == NULL)
return (0);
rcvs_native_RCVS = TRUE;
rcvs_put_options (argc, argv, rcvs_ID);
for (i=0; i<argc; i++)
rcvs_addlist (&rcvs_dirlist, rcvs_ID, argv[i], argv[i]);
return (0);
}
/* rcvs: check existing folders for 'remove' */
int
rcvs_remove (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 removing files/dirs */
for (i=0; i<argc; i++)
{
char *dir;
char *fn;
int found_folder = FALSE;
if ( isdir(argv[i])) /* remove dir */
error (1, 0, "cannot remove directories");
if (isfile (argv[i])) /* file exist */
{
command_name = xstrdup ("rcvs_remove");
error( 1, 0, " no files removed; use `rm' to remove the file first");
}
(void) strcpy (tmp, argv[i]);
fn = rindex (tmp, '/');
if (fn != NULL)
{
dir = tmp;
*fn++ = '\0';
}
else
{
dir = xstrdup (".");
fn = tmp;
}
sprintf (repository, "%s/%s", dir, CVSADM_REP);
if ( !isreadable ( repository))
error(1, 0,"rcvs_remove: %s is not a CVS folder", dir);
sprintf (repository,"%s/%s", repos, argv[i]);
rcvs_addlist (&rcvs_dirlist, ID, argv[i], repository);
}
return (0);
}
/* rcvs: collect information for rtag */
int
rcvs_rtag (argc, argv)
int argc;
char *argv[];
{
register int i;
if (rcvs_ID != NULL && index (rcvs_ID, ':') == NULL)
return (0);
rcvs_native_RCVS = TRUE;
rcvs_put_options (argc, argv, rcvs_ID);
for (i=0; i<argc; i++)
rcvs_addlist (&rcvs_dirlist, rcvs_ID, argv[i], argv[i]);
return (0);
}
/* rcvs: collect information for tag */
int
rcvs_tag (argc, argv)
int argc;
char *argv[];
{
register int i;
if (argc > 0)
{
rcvs_cmd_optind += 1;
argc -= 1;
argv += 1;
(void) rcvs_do_folder (argc, argv);
}
return (0);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.