This is rcvs_main.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 FILE *fp;
static struct cmd *cm;
static char *CurDir = NULL;
static char *host = NULL;
static char *margv[MAXARG];
static char msg1[] = "CVSROOT ----> clone";
static char msg2[] = "CVSROOT <---- clone";
static char bar[] = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
static char *rcvsid = NULL;
static int Margc = 0;
static int margc = 0;
static int lock_checked = FALSE;
static int get_CVSROOT = FALSE;
static int lockSet_onServer = FALSE;
static int phase1_err_reported = FALSE;
static char *cvsroot_gid;
static int cvsroot_mode;
static int local = FALSE;
/* version number */
int ver_rcvs_client = 0;
int ver_rcvs_server = 0;
/* flow control variables */
int rcvs_inshell = FALSE;
int rcvs_native = FALSE;
int rcvs_native_CVS = FALSE;
int rcvs_native_RCVS = FALSE;
int rcvs_set_p3_lock = FALSE;
int rcvs_sync = FALSE;
int rcvs_sync_backward = FALSE;
int rcvs_sync_forward = FALSE;
int rcvs_sync_check_error = 1;
int rcvs_copt_change_repos = FALSE;
int rcvs_Copt_change_repos = FALSE;
int rcvs_Ropt_remote = FALSE;
char *rcvs_Popt_phases = NULL;
/* lock variables */
int rcvs_lock_WFL_local = FALSE;
int rcvs_lock_WFL_remote = FALSE;
int rcvs_lock_RFL = FALSE;
int rcvs_lock_wfl = FALSE;
int rcvs_lock_rfl = FALSE;
int rcvs_Uopt_unlock = FALSE;
int rcvs_Lopt_lock = FALSE;
int rcvs_lock_phase3 = FALSE;
char *rcvs_ID = NULL;
char *rcvs_Id = NULL;
char *CVSroot_v = NULL;
char *CVSroot_n = NULL;
char *CVSrootr_v = NULL;
char *CVSrootr_n = NULL;
char *CVSrootd_v = NULL;
char *CVSrootd_n = NULL;
char *CVSrootD_v = NULL;
char *CVSrootD_n = NULL;
char *rcvs_domain = NULL;
char *rcvs_cvsrec = NULL;
char *rcvs_username = NULL;
char *rcvs_tmpname = NULL;
char *rcvs_module = NULL;
char *rcvs_dopt_where = NULL;
int rcvs_level = 0;
int rcvs_gen_optind = 0;
char *RCVSdir = NULL;
char *RCVShost = NULL;
char *RCVSroot = NULL;
char *RCVSuser = NULL;
struct CMD *rcvs_CM;
List *rcvs_chmodlist = (List *) NULL;
List *rcvs_rmlist = (List *) NULL;
List *rcvs_dirlist = (List *) NULL;
List *rcvs_filelist = (List *) NULL;
int rcvs_file_mode = FALSE;
int rcvs_cmd_optind;
int rcvs_parse_opt = FALSE;
int rcvs_do_rdist = TRUE;
char *rcvs_msgfile = NULL;
FILE *msgfp = (FILE *) NULL;
#if __STDC__
char *rcvs_get_repos (char *dir, char **Id, char **Repository);
int rcvs_do_host (int argc, char *argv[], Node *p);
int rcvs_add_sync_arg (int margc, char *margv[], Node *p);
int rcvs_add_original_arg (int margc, char *margv[], Node *p);
#else
char *rcvs_get_repos ();
int rcvs_do_host ();
int rcvs_add_sync_arg ();
int rcvs_add_original_arg ();
#endif /* __STDC__ */
struct cmd
{
char *fullname;
char *nick1;
char *nick2;
int (*func) ();
};
/* rcvs: this is core of RCVS. Process all folders if there is remote one */
int
rcvs_main (argc, argv, Cm)
int argc;
char *argv[];
struct cmd *Cm;
{
char tmp[PATH_MAX];
int err = 0;
cm = Cm;
/* initialization */
host = rcvs_gethostdomain ();
(void) sprintf (tmp,"%s.%d",RCVSMSG, getpid ());
rcvs_msgfile = xstrdup(tmp);
{
char *curDir;
curDir = xmalloc (PATH_MAX);
(void) getwd (curDir);
CurDir = xstrdup (curDir);
free (curDir);
}
/* adjust argument pointer */
argc += rcvs_gen_optind;
argv -= rcvs_gen_optind; /* e.g. ^cvs -t co -A me */
/* call rcvs_do_host */
if (rcvs_dirlist)
rcvs_walklist (argc, argv, "#4", rcvs_dirlist, rcvs_do_host);
else
error (1, 0, "rcvs_main: bug #1: no directory found");
/* return to main() only if there is only local folder */
exit (err);
}
/* rcvs: create an empty file then do chmod */
int
emptyfile (repository)
char *repository;
{
FILE *histfp;
if (!repository)
return(2);
histfp = open_file (repository, "w");
if (fclose (histfp))
{
error(0, 0,"emptyfile: cannot access %s", repository);
return(1);
}
(void) rcvs_chmod ( repository, cvsroot_gid, cvsroot_mode);
return(0);
}
/* rcvs: process folders that belong to a local or remote host. */
int
rcvs_do_host ( argc, argv, p )
int argc;
char *argv[];
Node *p;
{
int err = 0;
local = 0;
rcvsid = NULL;
margc = 0;
cvsroot_gid = NULL;
cvsroot_mode = 0;
if (rcvs_Popt_phases == NULL)
rcvs_Popt_phases = rcvs_CM->phases;
/* print name of folder */
{
List *L;
char tmp[PATH_MAX];
register int i;
tmp[0] = '\0';
L = (void *) p->data;
margc = Margc = 0;
rcvs_walklist (margc, margv, "#2", L, rcvs_add_sync_arg);
for ( i = 0; i < Margc; i++)
{
(void) strcat ( tmp, margv[i]);
(void) strcat ( tmp, " ");
}
if (!quiet)
{
char title[PATH_MAX];
if (index (p->key, ':') == NULL )
{
/*printf("<< LOCAL FOLDER >> %s\n", tmp);*/
(void) sprintf(title, "LOCAL FOLDER: %s", tmp);
}
else
{
/*printf("\n<< REMOTE FOLDER >> %s\n", tmp);*/
(void) sprintf(title, "REMOTE FOLDER: %s", tmp);
}
fprintf (stderr, "%s\n", title);
(void) strncpy (tmp, bar, strlen(title)-1);
*(tmp+strlen(title)-1) = '\0';
fprintf (stderr, "%s\n", tmp);
}
}
/* parse RCVS ID */
rcvsid = p->key;
(void) rcvs_Parse_ID (p->key, &RCVSuser, &RCVShost,
&RCVSroot,&RCVSdir, &CVSroot);
/* process this host in three phases */
{
if (index (p->key, ':') == NULL)
local = TRUE;
err = 0;
if (rcvs_msgfile != NULL && isfile(rcvs_msgfile))
if ( unlink_file (rcvs_msgfile) )
error (1, 0, "cannot remove message file %s\n", rcvs_msgfile);
if ( !local && index (rcvs_Popt_phases,'1') )
if ( !really_quiet || !noexec || trace)
err = rcvs_do_host_phase1 ( argc, argv, p );
if ( local || (! err && index (rcvs_Popt_phases,'2')) )
err = rcvs_do_host_phase2 (argc, argv, p);
if ( !local && (! err && index (rcvs_Popt_phases,'3')) )
if ( !really_quiet || !noexec || trace)
err = rcvs_do_host_phase3 (argc, argv, p);
/* append history + remove file + clear lock on server
* if 1. remove list not empty 2. no error 3. phase-3 4. has history
*/
{
char tmp[PATH_MAX];
char line[PATH_MAX];
(void) sprintf( tmp,"%s/CVSROOT/%s",CVSroot, CVSROOTADM_HISTORY_NEW);
if (rcvs_rmlist != NULL ||
(!local && (index (rcvs_Popt_phases,'3') || filesize(tmp))))
(void) rcvs_hist_and_lock(err, CVSroot, RCVSuser, RCVShost,
RCVSroot, RCVSdir);
/* clean up temporary history and commit file */
if (isfile(tmp) && !local)
unlink (tmp);
(void) sprintf( tmp,"%s/CVSROOT/%s",CVSroot, CVSROOTADM_COMMITLOG_NEW);
if (isfile(tmp) && !local)
unlink (tmp);
(void) sprintf( tmp,"%s/CVSROOT/%s",CVSroot, CVSROOTADM_HISTORY);
if (isfile(tmp) && !local)
emptyfile (tmp);
(void) sprintf( tmp,"%s/CVSROOT/%s",CVSroot, CVSROOTADM_COMMITLOG);
if (isfile(tmp) && !local)
emptyfile (tmp);
if (rcvs_msgfile != NULL && isfile(rcvs_msgfile))
(void) unlink(rcvs_msgfile);
}
rcvs_Clear_my_lock ();
if (cvsroot_gid)
free (cvsroot_gid);
}
return (err);
}
/* do chmod on a file or directory */
int
rcvs_chmod (repository, gid, mode)
char * repository;
char * gid;
int mode;
{
struct group *Gid;
if (isfile(repository) && gid)
{
struct stat sbuf;
uid_t uid;
if ( stat(repository, &sbuf) == 0)
{
uid = getuid();
Gid = getgrnam(gid);
if ( uid == sbuf.st_uid )
{
/* chgrp only if has group write access */
if ( S_IWGRP&(mode))
{
int err;
err = ( Gid == NULL ||
chown (repository, -1, Gid->gr_gid));
if (trace && err)
error(0,0, "cannot chgrp %s %s", gid, repository);
}
if ( chmod (repository, mode))
error(0,0, "cannot chmod %o %s", mode, repository);
}
}
}
}
/* examine stdout for sync session */
int
rcvs_check_sync_stdout(line)
char * line;
{
char *cp = NULL;
char tmp[PATH_MAX];
char repository[PATH_MAX];
int err = 0;
{
/* CVSROOT= */
if ( (strncmp ( "CVSROOT=", line, 8) == 0) ||
(strncmp ( "CVSroot=", line, 8) == 0) )
{
if (trace)
fprintf (stderr, "-> %s", line);
if (RCVSroot == NULL)
{
*(line + strlen(line) -1) = '\0';
cp = line + 8;
RCVSroot = xstrdup (cp);
}
/* CVSROOT= is a signal that CVS sync is ok !!
* CVSroot= is a signal that CVS lock on server is ok !!*/
if (strncmp ( "CVSROOT=", line, 8) == 0)
get_CVSROOT = TRUE;
else
lockSet_onServer = TRUE;
}
/* REMOVE= */
else if ( strncmp ( "REMOVE=", line, 7) == 0 )
{
if (trace)
fprintf (stderr, "-> %s", line);
*(line + strlen(line) -1) = '\0';
cp = line + 7;
sprintf (tmp, "%s/%s", CVSroot, cp);
if (trace && unlink_file (tmp))
fprintf (stderr, "-> cannot remove %s\n", cp);
}
/* GROUP/MODE= */
else if ( strncmp ( "GROUP/MODE=", line, 11) == 0 )
{
char dir[PATH_MAX];
char gid[PATH_MAX];
int mode;
if (trace)
fprintf (stderr, "-> %s", line);
*(line + strlen(line) -1) = '\0';
cp = line + 11;
sscanf (cp, "%s %s %o", dir, gid, &mode);
if (strcmp(dir,CVSROOTADM)== 0)
{
cvsroot_mode=mode;
cvsroot_gid=xstrdup(gid);
}
sprintf (repository, "%s/%s", CVSroot, dir);
(void) rcvs_chmod (repository, gid, mode);
}
/* RCVSLOCK= */
else if ( strncmp ( "RCVSLOCK=", line, 9) == 0 )
{
if (trace)
fprintf (stderr, "-> %s", line);
rcvs_lock_WFL_remote = TRUE;
}
else if ( strncmp ( "RSH_STATUS=", line, 11) == 0) /* RSH_STATUS */
{
int Err;
if (trace)
fprintf (stderr, "-> %s", line);
Err = atoi(line + 11);
if (Err)
{
fprintf (stderr, "rsh return err <> 0\n");
phase1_err_reported = TRUE;
err = Err;
}
}
/* RDIST_STATUS */
else if ( strncmp ( "RDIST_STATUS=1", line, 14) == 0)
{
if (trace)
fprintf (stderr, "-> %s", line);
fprintf (stderr, "rdist returns err <> 0\n");
phase1_err_reported = TRUE;
err = 1;
}
/* SERVER VERSION*/
else if ( strncmp ( "SERVER_VERSION=", line, 15) == 0)
{
if (trace)
fprintf (stderr, "-> %s", line);
*(line + strlen(line) -1) = '\0';
cp = line + 15;
ver_rcvs_server = (int)cp;
}
else
fprintf(stderr, "%s",line);
}
return (err);
}
/* rcvs: do forward sync for a remote folder. */
int
rcvs_do_host_phase1 ( argc, argv, p )
int argc;
char *argv[];
Node *p;
{
int err = 0;
int err2 = 0;
int err3 = 0;
FILE *fp_err;
char tmp[PATH_MAX];
char line[PATH_MAX];
List *L;
register int i;
get_CVSROOT = FALSE;
/* create clone directory if not already exist */
(void) rcvs_mkdir (RCVSdir);
/* check lock */
(void) rcvs_Check_lock ();
lock_checked = TRUE;
if (!quiet)
{
sprintf(line, "phase [1]. Sending rdist request to %s@%s",
RCVSuser, RCVShost);
fprintf (stderr, "%s\n", line);
if (trace)
{
(void) strncpy (tmp, bar, strlen(line));
*(tmp+strlen(line)) = '\0';
fprintf (stderr, "%s\n", tmp);
}
fprintf(stderr, "%s\n", msg1);
}
/* generate command to do rsh */
/*+IS*/
(void) sprintf (tmp,"%s %s -l %s ", rshcmd, RCVShost, RCVSuser );
/*-IS*/
(void) strcat ( tmp, "cvs " );
if (index(rcvs_Popt_phases,'3'))
(void) strcat ( tmp, "-L " );
if (noexec)
(void) strcat ( tmp, "-n " );
if (quiet)
(void) strcat ( tmp, "-q " );
if (really_quiet)
(void) strcat ( tmp, "-Q " );
if (trace)
(void) sprintf (tmp+strlen(tmp), "-t ");
if ( rcvs_Uopt_unlock)
(void) strcat ( tmp, "-U " );
(void) sprintf (tmp+strlen(tmp),"-S -e %d -d %s@%s:%s:%s ",
ver_rcvs, rcvs_username, host, RCVSdir, RCVSroot );
if (rcvs_cvsrec != NULL)
(void) sprintf (tmp+strlen(tmp),"-X %s ", rcvs_cvsrec );
(void) sprintf (tmp+strlen(tmp),"%s ", rcvs_CM->sync_name );
/* add relative repository stored in data field to margv */
L = (void *) p->data;
margc = Margc = 0;
rcvs_walklist (margc, margv, "#1", L, rcvs_add_sync_arg);
for ( i = 0; i < Margc; i++)
(void) sprintf (tmp+strlen(tmp), "%s ",margv[i]);
(void) strcat( tmp, "2>&1; echo RSH_STATUS=$?" );
/*-> put all cvs message into stdout */
if (trace)
(void) fprintf(stderr, "-> %s\n",tmp);
/* open pipe to receive data back from rsh */
fp = popen (tmp, "r");
/* check stdout, output from cvs's stdout */
if (trace)
(void) fprintf(stderr, "-> rcvs_do_host_phase1: output from stdout ...\n");
while (fgets (line, sizeof (line), fp))
{
if ( strncmp ( "|", line, 1) == 0) /* rdist message */
fprintf(stderr, "%s",line);
else
{
err = rcvs_check_sync_stdout (line);
if (err)
break;
(void) rcvs_check_rsh_output (line); /* give user suggestion */
}
}
err3 = pclose (fp);
if (err3)
{
if (!phase1_err_reported)
fprintf (stderr, "rsh return err <> 0\n");
phase1_err_reported = TRUE;
err = 1;
}
if (!get_CVSROOT && !phase1_err_reported)
{
fprintf (stderr, "cvs on server return err <> 0\n");
err = 1;
phase1_err_reported = TRUE;
}
if (err && !phase1_err_reported)
fprintf (stderr, "phase 1 returns err <> 0\n");
if (err && rcvs_CM->need_repos)
error (1, 0, "fail to get modules");
/* make sure history exist, it must exist to start history logging*/
(void) sprintf( line,"%s/CVSROOT/%s",CVSroot,CVSROOTADM_HISTORY);
if (!local && !isfile(line))
(void) emptyfile (line);
/* make sure commitlog exist */
(void) sprintf(line,"%s/CVSROOT/%s",CVSroot,CVSROOTADM_COMMITLOG);
if (!local && !isfile(line))
(void) emptyfile (line);
return (err);
}
/* rcvs: process folders locally. */
int
rcvs_do_host_phase2 ( argc, argv, p )
int argc;
char *argv[];
Node *p;
{
char tmp[PATH_MAX];
char line[PATH_MAX];
List *L;
int err = 0;
/* check lock */
if (!lock_checked)
(void) rcvs_Check_lock ();
lock_checked = TRUE;
if ( (chdir (CurDir) < 0))
error (1, 0, "cannot chdir to %s", CurDir);
/* run CVS command locally */
if (!quiet)
{
sprintf(line, "phase [2]. Local %s on clone",cm->fullname);
fprintf (stderr, "%s\n", line);
if (trace)
{
(void) strncpy (tmp, bar, strlen(line));
*(tmp+strlen(line)) = '\0';
fprintf (stderr, "%s\n", tmp);
}
fprintf(stderr,"%s\n", rcvs_CM->msg);
}
/* construct the argument for local cvs !! */
{
int i = 0;
int narg;
narg = rcvs_gen_optind + rcvs_cmd_optind -1;
(void) sprintf (tmp, "CVSROOT=%s; export CVSROOT; ", CVSroot);
for ( i = 0; i <= narg; i++)
{
if ( i == 1 )
{
if (index (p->key, ':') == NULL ) /* local folder */
(void) sprintf (tmp+strlen(tmp), "-Y %s -d %s ",
rcvs_msgfile, CVSroot_v);
else
(void) sprintf (tmp+strlen(tmp), "-Y %s -d %s ",
rcvs_msgfile, rcvsid);
}
if ( index (argv[i], ' ') != NULL )
(void) sprintf (tmp+strlen(tmp), "\'%s\' ", argv[i]);
else
{
if (i < rcvs_gen_optind && strcmp (argv[i], "-d") == 0)
i++;
else
{
(void) strcat ( tmp, argv[i]);
(void) strcat ( tmp, " ");
}
}
}
/* add relative repository of this folder to margv */
L = (void *) p->data;
margc = Margc = 0;
rcvs_walklist (margc, margv, "#2", L, rcvs_add_original_arg);
for ( i = 0; i < Margc; i++)
{
(void) strcat ( tmp, margv[i]);
(void) strcat ( tmp, " ");
}
}
/* run it in shell in order to catch error and/or set CVSROOT */
if (trace)
fprintf(stderr, "-> %s\n", tmp);
err = system ( tmp );
if (trace && err)
fprintf(stderr, "-> err=%d setlock=%d\n", err, rcvs_lock_WFL_local);
/* copy history to history.tmp and commitlog to commitlog.tmp */
(void) sprintf( tmp,"%s/CVSROOT/%s",CVSroot,CVSROOTADM_HISTORY);
(void) sprintf( line,"%s/CVSROOT/%s",CVSroot,CVSROOTADM_HISTORY_NEW);
if (!local && filesize(tmp))
{
copy_file (tmp, line);
(void) emptyfile (tmp);
}
(void) sprintf( tmp,"%s/CVSROOT/%s",CVSroot,CVSROOTADM_COMMITLOG);
(void) sprintf( line,"%s/CVSROOT/%s",CVSroot,CVSROOTADM_COMMITLOG_NEW);
if (!local && filesize(tmp))
{
copy_file (tmp, line);
(void) emptyfile (tmp);
}
/* cleanup lock if error */
if ( err )
{
int i;
fprintf (stderr, "phase 2 returns err <> 0\n");
if (index(rcvs_Popt_phases,'3'))
{
err = 0; /* reset error to sync back */
fprintf (stderr, "sync clone back anyway for safety..\n");
}
if (rcvs_native)
rcvs_Clear_my_lock ();
return (err);
}
return (0);
}
/* rcvs: do backward sync for remote folder that need to sync back. */
int
rcvs_do_host_phase3 ( argc, argv, p )
int argc;
char *argv[];
Node *p;
{
List *L;
char *Argv[MAXARG];
char tmp[PATH_MAX];
char line[PATH_MAX];
register int i;
int Argc;
int err = 0;
/* check lock */
if (!lock_checked)
(void) rcvs_Check_lock ();
lock_checked = TRUE;
/* cleanup lock if commit, then sync modules back to server */
{
/* rdist modules back to master repository,
* simply call checkout once rcs_sync flag is set
*/
if (!quiet)
{
sprintf (line,
"phase [3]. Rdist modules back to %s@%s", RCVSuser, RCVShost);
fprintf (stderr, "%s\n", line);
if (trace)
{
(void) strncpy (tmp, bar, strlen(line));
*(tmp+strlen(line)) = '\0';
fprintf (stderr, "%s\n", tmp);
}
fprintf(stderr, "%s\n", msg2);
}
/* add relative repository stored in data field to margv */
L = (void *) p->data;
margc = Margc = 0;
rcvs_walklist (margc, margv, "#3", L, rcvs_add_sync_arg);
Argv[0] = "checkout";
Argc=Margc + 1;
for ( i = 1; i <= Margc; i++)
Argv[i] = margv[i-1];
if (trace)
{
for ( i = 0; i < Argc; i++)
fprintf(stderr, "%s ", Argv[i]);
fprintf (stderr, "\n");
}
rcvs_sync = rcvs_sync_backward = TRUE;
rcvs_native = FALSE;
rcvs_chmodlist = rcvs_dirlist = rcvs_filelist = NULL;
/* skip phase 3 if -n */
if (noexec)
return;
if (strcmp (cm->fullname, "import") == 0)
{
err = rcvs_Rdist_init ();
(void) addlist (&rcvs_dirlist, Argv[1]);
err = rcvs_Rdist();
}
else
err = checkout (Argc, Argv);
rcvs_sync = rcvs_sync_backward = FALSE;
rcvs_native = TRUE;
}
if (err)
{
rcvs_lock_phase3 = TRUE;
/* construct instruction for recovering */
(void) sprintf (tmp, "cvs -U -P 3 ");
for ( i = 1; i < argc; i++)
{
if (strcmp(argv[i],"-P") == 0)
{
i++;
continue;
}
if (strcmp(argv[i],"-U") == 0)
continue;
(void) strcat ( tmp, argv[i]);
(void) strcat ( tmp, " ");
}
fprintf (stderr, "phase 3 returns err <> 0\n");
error (1, 0, "aborted, system remain locked.\nPlease do '%s' once the problem is solved ASAP !!!", tmp);
}
/* this is not the end yet. rcvs_hist_and_lock (in rcvs_lock.c) will
conduct the additional tasks:
1. Append history file to main repository.
2. Cleanup lock for commit.
3. Remove files if rmlist is not empty.
4. chmod for added directories.
*/
return (err);
}
/* determine CVSROOT */
int
rcvs_do_cvsroot (cvs_update_env)
int cvs_update_env;
{
int remote_mode = FALSE;
char *cvsroot;
char *cp;
if (rcvs_username == NULL)
rcvs_username = xstrdup (getcaller());
if (rcvs_cvsrec == NULL) /* get CVSREC */
{
if ((cp = getenv (CVSREC_ENV)) != NULL)
rcvs_cvsrec = cp;
}
if (rcvs_sync)
remote_mode = TRUE;
else /* check CVSMODE */
{
if ((cp = getenv (CVSMODE_ENV)) != NULL)
{
if ( strcmp (cp, "remote") == 0 || strcmp (cp, "REMOTE") == 0)
remote_mode = TRUE;
else if (!( strcmp (cp, "local") == 0 || strcmp (cp, "LOCAL") == 0))
error (1, 0, "set %s to 'local' or 'remote'", CVSMODE_ENV);
}
}
if (CVSrootd_v != NULL) /* -d */
{
rcvs_ID = CVSrootd_v;
rcvs_Id = CVSrootd_n;
if (index (rcvs_ID, ':') == NULL) /* local format */
{
CVSroot = CVSrootd_v;
CVSroot_v = CVSrootd_v;
CVSroot_n = CVSrootd_n;
}
else /* remote format */
{
if (rcvs_sync || rcvs_inshell)
(void) rcvs_Parse_ID (rcvs_ID, &RCVSuser, &RCVShost,
&RCVSroot,&RCVSdir, &CVSroot);
else
{
CVSrootr_v = rcvs_ID;
CVSrootr_n = rcvs_Id;
}
}
}
else /* no -d */
{
if (!remote_mode && CVSroot_v != NULL) /* CVSROOT */
{
rcvs_ID = CVSroot_v;
rcvs_Id = CVSroot_n;
if (index (rcvs_ID, ':') != NULL && (rcvs_sync || rcvs_inshell))
(void) rcvs_Parse_ID (rcvs_ID, &RCVSuser, &RCVShost,
&RCVSroot,&RCVSdir, &CVSroot);
}
if ( (remote_mode && CVSrootr_v != NULL) || /* CVSMODE=remote*/
(CVSroot_v == NULL && CVSrootr_v != NULL) ) /* CVSROOTr only*/
{
rcvs_ID = CVSrootr_v;
rcvs_Id = CVSrootr_n;
if (index (rcvs_ID, ':') != NULL)
(void) rcvs_Parse_ID (rcvs_ID, &RCVSuser, &RCVShost,
&RCVSroot,&RCVSdir, &cvsroot);
}
}
if (rcvs_Ropt_remote) /* -R */
{
if (CVSrootr_v == NULL || index (CVSrootr_v, ':') == NULL)
error (1, 0, "set %s to user@host:cvsroot:clone to use -R option", CVSROOTr_ENV);
rcvs_ID = CVSrootr_v;
rcvs_Id = CVSrootr_n;
}
if (rcvs_Copt_change_repos) /* -C */
{
if (CVSrootr_v == NULL || index (CVSrootr_v, ':') == NULL)
error (1, 0, "set %s to user@host:cvsroot:clone to use -C option", CVSROOTr_ENV);
rcvs_ID = CVSrootr_v;
rcvs_Id = CVSrootr_n;
}
if (rcvs_copt_change_repos) /* -c */
{
if (CVSroot_v == NULL)
{
CVSroot_v = rcvs_ID;
CVSroot_n = rcvs_Id;
}
if (CVSroot_v != NULL)
{
if (index (CVSroot_v, ':') == NULL)
{
rcvs_ID = CVSroot_v;
rcvs_Id = CVSroot_n;
}
else
error (1, 0, "set %s to local format to use -c option",
CVSROOT_ENV);
}
}
/* add user's name to ID if it's missing */
if (rcvs_ID != NULL && index (rcvs_ID, ':') != NULL)
{
cp = index (rcvs_ID, '@');
if (cp == NULL || cp == rcvs_ID)
{
char tmp[PATH_MAX];
if (cp == NULL)
sprintf (tmp, "%s@%s", rcvs_username, rcvs_ID);
else
sprintf (tmp, "%s%s", rcvs_username, rcvs_ID);
rcvs_ID = xstrdup (tmp);
}
}
if (rcvs_ID == NULL) /* neither CVSROOT nor CVSROOTr was set */
error (1, 0, "neither %s nor %s is set", CVSROOT_ENV, CVSROOTr_ENV);
/* print a warm fuzzy message */
if (!quiet && rcvs_ID != NULL && !rcvs_sync && !rcvs_inshell)
{
if (remote_mode && index (rcvs_ID, ':') != NULL)
{
fprintf (stderr, "turn on remote mode\n");
fprintf (stderr, "%s = %s\n", rcvs_Id, rcvs_ID);
}
}
}
/* rcvs: add argument for sync to buffer */
int
rcvs_add_sync_arg(margc, margv, p)
int margc;
char *margv[];
Node *p;
{
char *cp;
cp = p->data;
if (strcmp (cp, "") != 0)
margv[Margc++] = cp;
return 0;
}
/* rcvs: put original argument into buffer */
int
rcvs_add_original_arg(margc, margv, p)
int margc;
char *margv[];
Node *p;
{
char *cp;
cp = p->key;
margv[Margc++] = cp;
return (0);
}
/* create $RCVSDIR if not already exist */
int
rcvs_mkdir (rcvsdir)
char *rcvsdir;
{
char *cp = NULL;
char tmp[PATH_MAX];
char repository[PATH_MAX];
cp = rcvsdir;
if (!isdir (cp))
{
if ( mkdir ( cp, 0777) )
{
program_name = xstrdup ("rcvs_mkdir");
error (1, 0 ,"cannot create %s", cp);
}
else
{
chmod ( cp, 0775);
(void ) sprintf (tmp, "%s/%s", cp, RCVS_CLONE);
fp = open_file (tmp, "w");
fprintf (fp, "This is label for RCVS clone directory\n");
fprintf (fp, "Do not remove this file!\n");
if (fclose (fp) == EOF)
error (1, 0, "cannot close %s", tmp);
}
}
else
{
if (!iswritable (cp))
{
program_name = xstrdup ("rcvs_mkdir");
error (1, 0, "Sorry, you don't have sufficient access to %s", cp);
}
(void ) sprintf (tmp, "%s/%s", cp, RCVS_CLONE);
if (!isreadable (tmp))
{
fprintf(stderr,"Humm..directory %s is not labelled as clone,\n", cp);
fprintf(stderr,"if you're sure it can be used as clone, \n");
fprintf(stderr,"please type 'touch %s/%s' to create a label \n",
cp, RCVS_CLONE);
exit (1);
}
}
/* create CVSROOT if not already exist */
(void) strcpy(repository,rcvsdir);
(void) strcat(repository,"/CVSROOT");
cp = repository;
if (!isdir (cp))
if ( mkdir ( cp, 0777) )
{
program_name = xstrdup ("rcvs_mkdir");
error (1, 0 ,"cannot create %s", cp);
}
else
chmod ( cp, 0775);
else if (!iswritable (cp))
{
program_name = xstrdup ("rcvs_mkdir");
error (1, 0 , "Sorry, you don't have sufficient access to %s", cp);
}
return (0);
}
/* this is a special lock, if phase 3 is executed without phase 1,
* we need to set lock on server. This is done by executing
* 'cvs -S -L -P 9 co' on server
*/
int
rcvs_set_phase3_lock( )
{
int err = 0;
char line[PATH_MAX];
char tmp[PATH_MAX];
char *host = NULL;
host = rcvs_gethostdomain ();
/* generate command to do rsh */
/*+IS*/
(void) sprintf (tmp,"%s %s -l %s ", rshcmd, RCVShost, RCVSuser );
/*-IS*/
(void) strcat ( tmp, "cvs " );
if (index(rcvs_Popt_phases,'3'))
(void) strcat ( tmp, "-L -P 9 " );
if (trace)
(void) sprintf (tmp+strlen(tmp), "-t ");
if ( rcvs_Uopt_unlock)
(void) strcat ( tmp, "-U " );
(void) sprintf (tmp+strlen(tmp),
"-S -d %s@%s:%s:%s co 2>&1; echo RSH_STATUS=$?",
rcvs_username, host, RCVSdir, RCVSroot );
if (trace)
fprintf (stderr, "-> %s\n", tmp);
/* open pipe to receive data back from rsh */
fp = popen (tmp, "r");
if (trace)
(void) fprintf(stderr, "-> rcvs_set_phase3_lock: output from stdout ...\n");
while (fgets (line, sizeof (line), fp))
{
err = rcvs_check_sync_stdout (line);
if (err)
error (1, 0, "abort rcvs_set_phase3_lock");
}
if (pclose (fp))
error (1, 0, "rsh return err <> 0\n");
if (!lockSet_onServer)
error (1, 0, "fail to set lock\n");
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.