示例#1
0
void
cvs_repository_lock(const char *repo, int wantlock)
{
	int i;
	uid_t myuid;
	struct stat st;
	char fpath[MAXPATHLEN];
	struct passwd *pw;

	if (cvs_noexec == 1 || cvs_readonlyfs == 1)
		return;

	cvs_log(LP_TRACE, "cvs_repository_lock(%s, %d)", repo, wantlock);

	(void)xsnprintf(fpath, sizeof(fpath), "%s/%s", repo, CVS_LOCK);

	myuid = getuid();

	for (i = 0; i < CVS_LOCK_TRIES; i++) {
		if (cvs_quit)
			fatal("received signal %d", sig_received);

		if (stat(fpath, &st) == -1)
			break;

		if (st.st_uid == myuid)
			return;

		if ((pw = getpwuid(st.st_uid)) == NULL)
			fatal("cvs_repository_lock: %s", strerror(errno));

		cvs_log(LP_NOTICE, "waiting for %s's lock in '%s'",
		    pw->pw_name, repo);
		sleep(CVS_LOCK_SLEEP);
	}

	if (i == CVS_LOCK_TRIES)
		fatal("maximum wait time for lock inside '%s' reached", repo);

	if (wantlock == 0)
		return;

	if ((i = open(fpath, O_WRONLY|O_CREAT|O_TRUNC, 0755)) < 0) {
		if (errno == EEXIST)
			fatal("cvs_repository_lock: somebody beat us");
		else
			fatal("cvs_repository_lock: %s: %s",
			    fpath, strerror(errno));
	}

	(void)close(i);
	worklist_add(fpath, &repo_locks);
}
示例#2
0
文件: import.c 项目: UNGLinux/Obase
void
cvs_import_local(struct cvs_file *cf)
{
	int isnew;
	struct stat st;
	char repo[MAXPATHLEN];

	cvs_log(LP_TRACE, "cvs_import_local(%s)", cf->file_path);

	cvs_file_classify(cf, cvs_directory_tag);

	if (cf->file_type == CVS_DIR) {
		if (!strcmp(cf->file_path, "."))
			return;

		if (verbosity > 1)
			cvs_log(LP_NOTICE, "Importing %s", cf->file_path);

		if (cvs_noexec == 1)
			return;

		if (mkdir(cf->file_rpath, 0755) == -1 && errno != EEXIST)
			fatal("cvs_import_local: %s: %s", cf->file_rpath,
			    strerror(errno));

		return;
	}

	isnew = 1;
	(void)xsnprintf(repo, sizeof(repo), "%s/%s/%s/%s%s",
	    current_cvsroot->cr_dir, cf->file_wd, CVS_PATH_ATTIC,
	    cf->file_name, RCS_FILE_EXT);

	if (cf->file_rcs != NULL || stat(repo, &st) != -1)
		isnew = 0;

	if (isnew == 1)
		import_new(cf);
	else
		import_update(cf);
}
示例#3
0
void
cvs_repository_unlock(const char *repo)
{
	char fpath[MAXPATHLEN];

	cvs_log(LP_TRACE, "cvs_repository_unlock(%s)", repo);

	(void)xsnprintf(fpath, sizeof(fpath), "%s/%s", repo, CVS_LOCK);

	/* XXX - this ok? */
	worklist_run(&repo_locks, worklist_unlink);
}
示例#4
0
void
cvs_cleanup(void)
{
	cvs_log(LP_TRACE, "cvs_cleanup: removing locks");
	worklist_run(&repo_locks, worklist_unlink);

	cvs_log(LP_TRACE, "cvs_cleanup: removing temp files");
	worklist_run(&temp_files, worklist_unlink);

	if (cvs_server_path != NULL) {
		if (cvs_rmdir(cvs_server_path) == -1)
			cvs_log(LP_ERR,
			    "warning: failed to remove server directory: %s",
			    cvs_server_path);
		xfree(cvs_server_path);
		cvs_server_path = NULL;
	}

	if (current_list != NULL)
		cvs_ent_close(current_list, ENT_SYNC);
}
示例#5
0
static int
expand_var(BUF *buf, const char *var)
{
	struct passwd *pw;
	const char *val;

	if (*var == '=') {
		if ((val = cvs_var_get(++var)) == NULL) {
			cvs_log(LP_ERR, "no such user variable ${=%s}", var);
			return (1);
		}
		buf_puts(buf, val);
	} else {
		if (strcmp(var, "CVSEDITOR") == 0 ||
		    strcmp(var, "EDITOR") == 0 ||
		    strcmp(var, "VISUAL") == 0)
			buf_puts(buf, cvs_editor);
		else if (strcmp(var, "CVSROOT") == 0)
			buf_puts(buf, current_cvsroot->cr_dir);
		else if (strcmp(var, "USER") == 0) {
			pw = getpwuid(geteuid());
			if (pw == NULL) {
				cvs_log(LP_ERR, "unable to retrieve "
				    "caller ID");
				return (1);
			}
			buf_puts(buf, pw->pw_name);
		} else if (strcmp(var, "RCSBIN") == 0) {
			cvs_log(LP_ERR, "RCSBIN internal variable is no "
			    "longer supported");
			return (1);
		} else {
			cvs_log(LP_ERR, "no such internal variable $%s", var);
			return (1);
		}
	}

	return (0);
}
示例#6
0
/*
 * cvs_var_set()
 *
 * Set the value of the variable <var> to <val>.  If there is no such variable,
 * a new entry is created, otherwise the old value is overwritten.
 * Returns 0 on success, or -1 on failure.
 */
int
cvs_var_set(const char *var, const char *val)
{
	const char *cp;
	struct cvs_var *vp;

	if (var == NULL || *var == '\0') {
		cvs_log(LP_ERR, "no variable name");
		return (-1);
	}

	/* sanity check on the name */
	for (cp = var; *cp != '\0'; cp++)
		if (!isalnum((unsigned char)*cp) && (*cp != '_')) {
			cvs_log(LP_ERR,
			    "variable name `%s' contains invalid characters",
			    var);
			return (-1);
		}

	TAILQ_FOREACH(vp, &cvs_variables, cv_link)
		if (strcmp(vp->cv_name, var) == 0)
			break;

	if (vp == NULL) {
		vp = xcalloc(1, sizeof(*vp));

		vp->cv_name = xstrdup(var);
		TAILQ_INSERT_TAIL(&cvs_variables, vp, cv_link);

	} else	/* free the previous value */
		xfree(vp->cv_val);

	vp->cv_val = xstrdup(val);

	return (0);
}
示例#7
0
文件: add.c 项目: UNGLinux/Obase
void
cvs_add_local(struct cvs_file *cf)
{
	cvs_log(LP_TRACE, "cvs_add_local(%s)", cf->file_path);

	if (cvs_cmdop != CVS_OP_CHECKOUT && cvs_cmdop != CVS_OP_UPDATE)
		cvs_file_classify(cf, cvs_directory_tag);

	/* dont use `cvs add *' */
	if (strcmp(cf->file_name, ".") == 0 ||
	    strcmp(cf->file_name, "..") == 0 ||
	    strcmp(cf->file_name, CVS_PATH_CVSDIR) == 0) {
		if (verbosity > 1)
			cvs_log(LP_ERR,
			    "cannot add special file `%s'; skipping",
			    cf->file_name);
		return;
	}

	if (cf->file_type == CVS_DIR)
		add_directory(cf);
	else
		add_file(cf);
}
示例#8
0
void
cvs_server_static_directory(char *data)
{
	FILE *fp;
	char fpath[MAXPATHLEN];

	(void)xsnprintf(fpath, MAXPATHLEN, "%s/%s",
	    server_currentdir, CVS_PATH_STATICENTRIES);

	if ((fp = fopen(fpath, "w+")) == NULL) {
		cvs_log(LP_ERRNO, "%s", fpath);
		return;
	}
	(void)fclose(fp);
}
示例#9
0
void
cvs_server_send_response(char *fmt, ...)
{
	int i;
	va_list ap;
	char *data;

	va_start(ap, fmt);
	i = vasprintf(&data, fmt, ap);
	va_end(ap);
	if (i == -1)
		fatal("cvs_server_send_response: could not allocate memory");

	cvs_log(LP_TRACE, "%s", data);
	cvs_remote_output(data);
	xfree(data);
}
示例#10
0
void
cvs_server_sticky(char *data)
{
	FILE *fp;
	char tagpath[MAXPATHLEN];

	if (data == NULL)
		fatal("Missing argument for Sticky");

	(void)xsnprintf(tagpath, MAXPATHLEN, "%s/%s",
	    server_currentdir, CVS_PATH_TAG);

	if ((fp = fopen(tagpath, "w+")) == NULL) {
		cvs_log(LP_ERRNO, "%s", tagpath);
		return;
	}

	(void)fprintf(fp, "%s\n", data);
	(void)fclose(fp);
}
示例#11
0
/*
 * cvsroot_get()
 *
 * Get the CVSROOT information for a specific directory <dir>.  The
 * value is taken from one of 3 possible sources (in order of precedence):
 *
 * 1) the `-d' command-line option
 * 2) the CVS/Root file found in checked-out trees
 * 3) the CVSROOT environment variable
 */
struct cvsroot *
cvsroot_get(const char *dir)
{
	char rootpath[MAXPATHLEN], *rootstr, line[128];
	FILE *fp;

	if (cvs_rootstr != NULL)
		return cvsroot_parse(cvs_rootstr);

	if (cvs_server_active == 1)
		return cvsroot_parse(dir);

	if (cvs_cmdop == CVS_OP_IMPORT)
		return NULL;

	(void)xsnprintf(rootpath, MAXPATHLEN, "%s/%s", dir, CVS_PATH_ROOTSPEC);

	if ((fp = fopen(rootpath, "r")) == NULL) {
		if (errno == ENOENT) {
			/* try env as a last resort */
			if ((rootstr = getenv("CVSROOT")) != NULL)
				return cvsroot_parse(rootstr);
			else
				return (NULL);
		} else {
			fatal("cvsroot_get: fopen: `%s': %s",
			    CVS_PATH_ROOTSPEC, strerror(errno));
		}
	}

	if (fgets(line, (int)sizeof(line), fp) == NULL)
		fatal("cvsroot_get: fgets: `%s'", CVS_PATH_ROOTSPEC);

	(void)fclose(fp);

	line[strcspn(line, "\n")] = '\0';
	if (line[0] == '\0')
		cvs_log(LP_ERR, "empty %s file", CVS_PATH_ROOTSPEC);

	return cvsroot_parse(line);
}
示例#12
0
int
config_parse_line(char *line, int lineno)
{
	struct rlimit rl;
	const char *errstr;
	char *val, *opt, *ep;

	opt = line;
	if ((val = strrchr(opt, '=')) == NULL)
		fatal("cvs_parse_configfile: bad option '%s'", opt);

	*(val++) = '\0';

	if (!strcmp(opt, "tag")) {
		free(cvs_tagname);
		cvs_tagname = xstrdup(val);
	} else if (!strcmp(opt, "umask")) {
		cvs_umask = strtol(val, &ep, 8);

		if (val == ep || *ep != '\0')
			fatal("cvs_parse_configfile: umask %s is "
			    "invalid", val);
		if (cvs_umask < 0 || cvs_umask > 07777)
			fatal("cvs_parse_configfile: umask %s is "
			    "invalid", val);
	} else if (!strcmp(opt, "dlimit")) {
		if (getrlimit(RLIMIT_DATA, &rl) != -1) {
			rl.rlim_cur = (int)strtonum(val, 0, INT_MAX,
			    &errstr);
			if (errstr != NULL)
				fatal("cvs_parse_configfile: %s: %s",
				    val, errstr);
			rl.rlim_cur = rl.rlim_cur * 1024;
			(void)setrlimit(RLIMIT_DATA, &rl);
		}
	} else {
		cvs_log(LP_ERR, "ignoring unknown option '%s'", opt);
	}

	return (0);
}
示例#13
0
文件: add.c 项目: UNGLinux/Obase
void
cvs_add_remote(struct cvs_file *cf)
{
	char path[MAXPATHLEN];

	cvs_log(LP_TRACE, "cvs_add_remote(%s)", cf->file_path);

	cvs_file_classify(cf, cvs_directory_tag);

	if (cf->file_type == CVS_DIR) {
		cvs_get_repository_path(cf->file_wd, path, MAXPATHLEN);
		if (strlcat(path, "/", sizeof(path)) >= sizeof(path))
			fatal("cvs_add_remote: truncation");
		if (strlcat(path, cf->file_path, sizeof(path)) >= sizeof(path))
			fatal("cvs_add_remote: truncation");
		cvs_client_send_request("Directory %s\n%s", cf->file_path,
		    path);

		add_directory(cf);
	} else {
		cvs_client_sendfile(cf);
	}
}
示例#14
0
文件: buf.c 项目: UNGLinux/Obase
/*
 * Write the contents of the buffer <b> to the file whose path is given in
 * <path>.  If the file does not exist, it is created with mode <mode>.
 */
int
buf_write(BUF *b, const char *path, mode_t mode)
{
	int fd;
open:
	if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, mode)) == -1) {
		if (errno == EACCES && unlink(path) != -1)
			goto open;
		else
			fatal("open: `%s': %s", path, strerror(errno));
	}

	if (buf_write_fd(b, fd) == -1) {
		(void)unlink(path);
		fatal("buf_write: buf_write_fd: `%s'", path);
	}

	if (fchmod(fd, mode) < 0)
		cvs_log(LP_ERR, "permissions not set on file %s", path);

	(void)close(fd);

	return (0);
}
示例#15
0
文件: import.c 项目: UNGLinux/Obase
int
cvs_import(int argc, char **argv)
{
	int i, ch;
	char repo[MAXPATHLEN], *arg = ".";
	struct cvs_recursion cr;
	struct trigger_list *line_list;

	while ((ch = getopt(argc, argv, cvs_cmd_import.cmd_opts)) != -1) {
		switch (ch) {
		case 'b':
			import_branch = optarg;
			break;
		case 'd':
			dflag = 1;
			break;
		case 'k':
			koptstr = optarg;
			kflag = rcs_kflag_get(koptstr);
			if (RCS_KWEXP_INVAL(kflag)) {
				cvs_log(LP_ERR,
				    "invalid RCS keyword expansion mode");
				fatal("%s", cvs_cmd_import.cmd_synopsis);
			}
			break;
		case 'm':
			logmsg = optarg;
			break;
		default:
			fatal("%s", cvs_cmd_import.cmd_synopsis);
			break;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < 3)
		fatal("%s", cvs_cmd_import.cmd_synopsis);

	import_repository = argv[0];
	vendor_tag = argv[1];
	argc -= 2;
	argv += 2;

	release_tags = argv;
	tagcount = argc;

	if (!rcs_sym_check(vendor_tag))
		fatal("invalid symbol: %s", vendor_tag);

	for (i = 0; i < tagcount; i++) {
		if (!rcs_sym_check(release_tags[i]))
			fatal("invalid symbol: %s", release_tags[i]);
	}

	if (logmsg == NULL) {
		if (cvs_server_active)
			fatal("no log message specified");
		else
			logmsg = cvs_logmsg_create(NULL, NULL, NULL, NULL);
	}

	if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
		cvs_client_connect_to_server();

		cvs_client_send_request("Argument -b%s", IMPORT_DEFAULT_BRANCH);

		if (kflag)
			cvs_client_send_request("Argument -k%s", koptstr);

		cvs_client_send_logmsg(logmsg);
		cvs_client_send_request("Argument %s", import_repository);
		cvs_client_send_request("Argument %s", vendor_tag);
		for (i = 0; i < tagcount; i++)
			cvs_client_send_request("Argument %s", release_tags[i]);

		cr.enterdir = NULL;
		cr.leavedir = NULL;
		cr.fileproc = cvs_client_sendfile;
		cr.flags = CR_RECURSE_DIRS;

		cvs_file_run(1, &arg, &cr);
		cvs_client_senddir(".");
		cvs_client_send_request("import");

		cvs_client_get_responses();
		return (0);
	}

	if (cvs_logmsg_verify(logmsg))
		return (0);

	(void)xsnprintf(repo, sizeof(repo), "%s/%s",
	    current_cvsroot->cr_dir, import_repository);

	import_loginfo(import_repository);

	if (cvs_noexec != 1)
		cvs_mkdir(repo, 0755);

	cr.enterdir = NULL;
	cr.leavedir = NULL;
	cr.fileproc = cvs_import_local;
	cr.flags = CR_RECURSE_DIRS;
	cvs_file_run(1, &arg, &cr);

	if (import_conflicts != 0) {
		import_printf("\n%d conflicts created by this import.\n\n",
		    import_conflicts);
		import_printf("Use the following command to help the merge:\n");
		import_printf("\topencvs checkout ");
		import_printf("-j%s:yesterday -j%s %s\n\n", vendor_tag,
		    vendor_tag, import_repository);
	} else {
		import_printf("\nNo conflicts created by this import.\n\n");
	}

	loginfo = buf_release(logbuf);
	logbuf = NULL;

	line_list = cvs_trigger_getlines(CVS_PATH_LOGINFO, import_repository);
	if (line_list != NULL) {
		cvs_trigger_handle(CVS_TRIGGER_LOGINFO, import_repository,
		    loginfo, line_list, NULL);
		cvs_trigger_freelist(line_list);
	}

	xfree(loginfo);
	return (0);
}
示例#16
0
文件: import.c 项目: UNGLinux/Obase
static void
import_update(struct cvs_file *cf)
{
	int ret;
	BUF *b1, *b2, *d;
	char branch[CVS_REV_BUFSZ];
	RCSNUM *newrev, *rev, *brev;

	cvs_log(LP_TRACE, "import_update(%s)", cf->file_path);

	if (cf->file_rcs->rf_head == NULL)
		fatal("no head revision in RCS file for `%s'", cf->file_path);

	if ((rev = rcs_translate_tag(import_branch, cf->file_rcs)) == NULL)
		fatal("import_update: could not translate tag `%s'",
		    import_branch);

	if ((brev = rcsnum_parse(import_branch)) == NULL)
		fatal("import_update: rcsnum_parse failed");

	b1 = rcs_rev_getbuf(cf->file_rcs, rev, RCS_KWEXP_NONE);
	b2 = buf_load_fd(cf->fd);

	ret = buf_differ(b1, b2);
	buf_free(b1);
	buf_free(b2);
	if (ret == 0) {
		import_tag(cf, brev, rev);
		rcsnum_free(brev);
		if (cvs_noexec != 1)
			rcs_write(cf->file_rcs);
		import_printf("U %s/%s\n", import_repository, cf->file_path);
		return;
	}

	if (cf->file_rcs->rf_branch != NULL)
		rcsnum_tostr(cf->file_rcs->rf_branch, branch, sizeof(branch));

	if (cf->file_rcs->rf_branch == NULL || cf->in_attic == 1 ||
	    strcmp(branch, import_branch)) {
		import_conflicts++;
		import_printf("C %s/%s\n", import_repository, cf->file_path);
	} else {
		import_printf("U %s/%s\n", import_repository, cf->file_path);
	}

	if (cvs_noexec == 1)
		return;

	d = import_get_rcsdiff(cf, rev);
	newrev = rcsnum_inc(rev);

	if (rcs_rev_add(cf->file_rcs, newrev, logmsg, -1, NULL) == -1)
		fatal("import_update: failed to add new revision");

	if (rcs_deltatext_set(cf->file_rcs, newrev, d) == -1)
		fatal("import_update: failed to set deltatext");

	import_tag(cf, brev, newrev);

	if (kflag)
		rcs_kwexp_set(cf->file_rcs, kflag);

	rcsnum_free(brev);
	rcs_write(cf->file_rcs);
}
示例#17
0
文件: import.c 项目: UNGLinux/Obase
static void
import_new(struct cvs_file *cf)
{
	int i;
	BUF *bp;
	mode_t mode;
	time_t tstamp;
	struct stat st;
	struct rcs_branch *brp;
	struct rcs_delta *rdp;
	RCSNUM *branch, *brev;

	tstamp = -1;

	cvs_log(LP_TRACE, "import_new(%s)", cf->file_name);

	if (cvs_noexec == 1) {
		import_printf("N %s/%s\n", import_repository, cf->file_path);
		return;
	}

	if (fstat(cf->fd, &st) == -1)
		fatal("import_new: %s", strerror(errno));

	mode = st.st_mode;

	if (dflag == 1)
		tstamp = st.st_mtime;

	if ((branch = rcsnum_parse(import_branch)) == NULL)
		fatal("import_new: failed to parse branch");

	bp = buf_load_fd(cf->fd);

	if ((brev = rcsnum_brtorev(branch)) == NULL)
		fatal("import_new: failed to get first branch revision");

	cf->repo_fd = open(cf->file_rpath, O_CREAT | O_RDONLY);
	if (cf->repo_fd < 0)
		fatal("import_new: %s: %s", cf->file_rpath, strerror(errno));

	cf->file_rcs = rcs_open(cf->file_rpath, cf->repo_fd, RCS_CREATE,
	    (mode & ~(S_IWUSR | S_IWGRP | S_IWOTH)));
	if (cf->file_rcs == NULL)
		fatal("import_new: failed to create RCS file for %s",
		    cf->file_path);

	rcs_branch_set(cf->file_rcs, branch);

	if (rcs_sym_add(cf->file_rcs, vendor_tag, branch) == -1)
		fatal("import_new: failed to add vendor tag");

	for (i = 0; i < tagcount; i++) {
		if (rcs_sym_add(cf->file_rcs, release_tags[i], brev) == -1)
			fatal("import_new: failed to add release tag");
	}

	if (rcs_rev_add(cf->file_rcs, brev, logmsg, tstamp, NULL) == -1)
		fatal("import_new: failed to create first branch revision");

	if (rcs_rev_add(cf->file_rcs, RCS_HEAD_REV, "Initial revision",
	    tstamp, NULL) == -1)
		fatal("import_new: failed to create first revision");

	if ((rdp = rcs_findrev(cf->file_rcs, cf->file_rcs->rf_head)) == NULL)
		fatal("import_new: cannot find newly added revision");

	brp = xmalloc(sizeof(*brp));
	brp->rb_num = rcsnum_alloc();
	rcsnum_cpy(brev, brp->rb_num, 0);
	TAILQ_INSERT_TAIL(&(rdp->rd_branches), brp, rb_list);

	if (rcs_deltatext_set(cf->file_rcs,
	    cf->file_rcs->rf_head, bp) == -1)
		fatal("import_new: failed to set deltatext");

	if (kflag)
		rcs_kwexp_set(cf->file_rcs, kflag);

	rcs_write(cf->file_rcs);
	import_printf("N %s/%s\n", import_repository, cf->file_path);

	rcsnum_free(branch);
	rcsnum_free(brev);
}
示例#18
0
文件: add.c 项目: UNGLinux/Obase
int
cvs_add(int argc, char **argv)
{
	int ch;
	int flags;
	struct cvs_recursion cr;

	flags = CR_REPO;

	while ((ch = getopt(argc, argv, cvs_cmd_add.cmd_opts)) != -1) {
		switch (ch) {
		case 'k':
			kflag = rcs_kflag_get(optarg);
			if (RCS_KWEXP_INVAL(kflag)) {
				cvs_log(LP_ERR,
				    "invalid RCS keyword expansion mode");
				fatal("%s", cvs_cmd_add.cmd_synopsis);
			}
			(void)xsnprintf(kbuf, sizeof(kbuf), "-k%s", optarg);
			break;
		case 'm':
			logmsg = optarg;
			break;
		default:
			fatal("%s", cvs_cmd_add.cmd_synopsis);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc == 0)
		fatal("%s", cvs_cmd_add.cmd_synopsis);

	cr.enterdir = NULL;
	cr.leavedir = NULL;

	if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
		cvs_client_connect_to_server();
		cr.fileproc = cvs_add_remote;
		flags = 0;

		if (kflag)
			cvs_client_send_request("Argument %s", kbuf);

		if (logmsg != NULL)
			cvs_client_send_logmsg(logmsg);
	} else {
		if (logmsg != NULL && cvs_logmsg_verify(logmsg))
			return (0);

		cr.fileproc = cvs_add_local;
	}

	cr.flags = flags;

	cvs_file_run(argc, argv, &cr);

	if (added_files != 0) {
		cvs_log(LP_NOTICE, "use '%s commit' to add %s "
		    "permanently", __progname,
		    (added_files == 1) ? "this file" : "these files");
	}

	if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
		cvs_client_senddir(".");
		cvs_client_send_files(argv, argc);
		cvs_client_send_request("add");
		cvs_client_get_responses();

		if (server_response == SERVER_OK) {
			cr.fileproc = cvs_add_entry;
			cvs_file_run(argc, argv, &cr);
		}
	}

	return (0);
}
示例#19
0
文件: admin.c 项目: UNGLinux/Obase
void
cvs_admin_local(struct cvs_file *cf)
{
	int i;
	RCSNUM *rev;

	cvs_log(LP_TRACE, "cvs_admin_local(%s)", cf->file_path);

	cvs_file_classify(cf, cvs_directory_tag);

	if (cf->file_type == CVS_DIR) {
		if (verbosity > 1)
			cvs_log(LP_NOTICE, "Administrating %s", cf->file_name);
		return;
	}

	if (cf->file_ent == NULL)
		return;
	else if (cf->file_status == FILE_ADDED) {
		cvs_log(LP_ERR, "cannot admin newly added file `%s'",
		    cf->file_name);
		return;
	}

	if (cf->file_rcs == NULL) {
		cvs_log(LP_ERR, "lost RCS file for `%s'", cf->file_path);
		return;
	}

	if (verbosity > 0)
		cvs_printf("RCS file: %s\n", cf->file_rcs->rf_path);

	if (oldfilename != NULL) {
		struct cvs_file *ocf;
		struct rcs_access *acp;
		int ofd;
		char *d, *f, fpath[MAXPATHLEN], repo[MAXPATHLEN];


		if ((f = basename(oldfilename)) == NULL)
			fatal("cvs_admin_local: basename failed");
		if ((d = dirname(oldfilename)) == NULL)
			fatal("cvs_admin_local: dirname failed");

		cvs_get_repository_path(d, repo, MAXPATHLEN);

		(void)xsnprintf(fpath, MAXPATHLEN, "%s/%s", repo, f);

		if (strlcat(fpath, RCS_FILE_EXT, MAXPATHLEN) >= MAXPATHLEN)
			fatal("cvs_admin_local: truncation");

		if ((ofd = open(fpath, O_RDONLY)) == -1)
			fatal("cvs_admin_local: open: `%s': %s", fpath,
			    strerror(errno));

		/* XXX: S_ISREG() check instead of blindly using CVS_FILE? */
		ocf = cvs_file_get_cf(d, f, oldfilename, ofd, CVS_FILE, 0);

		ocf->file_rcs = rcs_open(fpath, ofd, RCS_READ, 0444);
		if (ocf->file_rcs == NULL)
			fatal("cvs_admin_local: rcs_open failed");

		TAILQ_FOREACH(acp, &(ocf->file_rcs->rf_access), ra_list)
			rcs_access_add(cf->file_rcs, acp->ra_name);

		cvs_file_free(ocf);
	}

	if (alist != NULL) {
		struct cvs_argvector *aargv;

		aargv = cvs_strsplit(alist, ",");
		for (i = 0; aargv->argv[i] != NULL; i++)
			rcs_access_add(cf->file_rcs, aargv->argv[i]);

		cvs_argv_destroy(aargv);
	}

	if (comment != NULL)
		rcs_comment_set(cf->file_rcs, comment);

	if (elist != NULL) {
		struct cvs_argvector *eargv;

		eargv = cvs_strsplit(elist, ",");
		for (i = 0; eargv->argv[i] != NULL; i++)
			rcs_access_remove(cf->file_rcs, eargv->argv[i]);

		cvs_argv_destroy(eargv);
	} else if (runflags & ADM_EFLAG) {
		struct rcs_access *rap;

		while (!TAILQ_EMPTY(&(cf->file_rcs->rf_access))) {
			rap = TAILQ_FIRST(&(cf->file_rcs->rf_access));
			TAILQ_REMOVE(&(cf->file_rcs->rf_access), rap, ra_list);
			xfree(rap->ra_name);
			xfree(rap);
		}
		/* no synced anymore */
		cf->file_rcs->rf_flags &= ~RCS_SYNCED;
	}

	/* Default `-kv' is accepted here. */
	if (kflag) {
		if (cf->file_rcs->rf_expand == NULL ||
		    strcmp(cf->file_rcs->rf_expand, koptstr) != 0)
			rcs_kwexp_set(cf->file_rcs, kflag);
	}

	if (logstr != NULL) {
		if ((logmsg = strchr(logstr, ':')) == NULL) {
			cvs_log(LP_ERR, "missing log message");
			return;
		}

		*logmsg++ = '\0';
		if ((rev = rcsnum_parse(logstr)) == NULL) {
			cvs_log(LP_ERR, "`%s' bad revision number", logstr);
			return;
		}

		if (rcs_rev_setlog(cf->file_rcs, rev, logmsg) < 0) {
			cvs_log(LP_ERR, "failed to set logmsg for `%s' to `%s'",
			    logstr, logmsg);
			rcsnum_free(rev);
			return;
		}

		rcsnum_free(rev);
	}

	if (orange != NULL) {
		struct rcs_delta *rdp, *nrdp;
		char b[CVS_REV_BUFSZ];

		cvs_revision_select(cf->file_rcs, orange);
		for (rdp = TAILQ_FIRST(&(cf->file_rcs->rf_delta));
		    rdp != NULL; rdp = nrdp) {
			nrdp = TAILQ_NEXT(rdp, rd_list);

			/*
			 * Delete selected revisions.
			 */
			if (rdp->rd_flags & RCS_RD_SELECT) {
				rcsnum_tostr(rdp->rd_num, b, sizeof(b));
				if (verbosity > 0)
					cvs_printf("deleting revision %s\n", b);

				(void)rcs_rev_remove(cf->file_rcs, rdp->rd_num);
			}
		}
	}

	if (state != NULL) {
		if (staterevstr != NULL) {
			if ((rev = rcsnum_parse(staterevstr)) == NULL) {
				cvs_log(LP_ERR, "`%s' bad revision number",
				    staterevstr);
				return;
			}
		} else if (cf->file_rcs->rf_head != NULL) {
			rev = rcsnum_alloc();
			rcsnum_cpy(cf->file_rcs->rf_head, rev, 0);
		} else {
			cvs_log(LP_ERR, "head revision missing");
			return;
		}

		(void)rcs_state_set(cf->file_rcs, rev, state);

		rcsnum_free(rev);
	}

	if (lkmode != RCS_LOCK_INVAL)
		(void)rcs_lock_setmode(cf->file_rcs, lkmode);

	rcs_write(cf->file_rcs);

	if (verbosity > 0)
		cvs_printf("done\n");
}
示例#20
0
static char *
parse_cmd(int type, char *cmd, const char *repo,
    struct file_info_list *file_info)
{
	int expanded = 0;
	char argbuf[2] = { '\0', '\0' };
	char *allowed_args, *default_args, *args, *file, *p, *q = NULL;
	size_t pos;
	BUF *buf;

	switch (type) {
	case CVS_TRIGGER_COMMITINFO:
		allowed_args = "prsS{}";
		default_args = " %p/%r %S";
		file = CVS_PATH_COMMITINFO;
		break;
	case CVS_TRIGGER_LOGINFO:
		allowed_args = "prsSvVt{}";
		default_args = NULL;
		file = CVS_PATH_LOGINFO;
		break;
	case CVS_TRIGGER_VERIFYMSG:
		allowed_args = "l";
		default_args = " %l";
		file = CVS_PATH_VERIFYMSG;
		break;
	case CVS_TRIGGER_TAGINFO:
		allowed_args = "btoprsSvV{}";
		default_args = " %t %o %p/%r %{sv}";
		file = CVS_PATH_TAGINFO;
		break;
	default:
		return (NULL);
	}

	/* before doing any stuff, check if the command starts with % */
	for (p = cmd;
	     *p != '%' && !isspace((unsigned char)*p) && *p != '\0'; p++)
		;
	if (*p == '%')
		return (NULL);

	buf = buf_alloc(1024);

	p = cmd;
again:
	for (; *p != '\0'; p++) {
		if ((pos = strcspn(p, "$%")) != 0) {
			buf_append(buf, p, pos);
			p += pos;
		}

		q = NULL;
		if (*p == '\0')
			break;
		if (*p++ == '$') {
			if (*p == '{') {
				pos = strcspn(++p, "}");
				if (p[pos] == '\0')
					goto bad;
			} else {
				for (pos = 0; isalpha(p[pos]); pos++)
					;
				if (pos == 0) {
					cvs_log(LP_ERR,
					    "unrecognized variable syntax");
					goto bad;
				}
			}
			q = xmalloc(pos + 1);
			memcpy(q, p, pos);
			q[pos] = '\0';
			if (expand_var(buf, q))
				goto bad;
			p += pos - (*(p - 1) == '{' ? 0 : 1);
		} else {
			switch (*p) {
			case '\0':
				goto bad;
			case '{':
				if (strchr(allowed_args, '{') == NULL)
					goto bad;
				pos = strcspn(++p, "}");
				if (p[pos] == '\0')
					goto bad;
				q = xmalloc(pos + 1);
				memcpy(q, p, pos);
				q[pos] = '\0';
				args = q;
				p += pos;
				break;
			default:
				argbuf[0] = *p;
				args = argbuf;
				break;
			}
	
			if (expand_args(buf, file_info, repo, allowed_args,
			    args))
				goto bad;
			expanded = 1;
		}

		free(q);
	}

	if (!expanded && default_args != NULL) {
		p = default_args;
		expanded = 1;
		goto again;
	}

	buf_putc(buf, '\0');
	return (buf_release(buf));

bad:
	free(q);
	cvs_log(LP_NOTICE, "%s contains malformed command '%s'", file, cmd);
	buf_free(buf);
	return (NULL);
}
示例#21
0
void
cvs_history_add(int type, struct cvs_file *cf, const char *argument)
{
	BUF *buf;
	FILE *fp;
	RCSNUM *hrev;
	size_t len;
	int fd;
	char *cwd, *p, *rev;
	char revbuf[CVS_REV_BUFSZ], repo[MAXPATHLEN], fpath[MAXPATHLEN];
	char timebuf[CVS_TIME_BUFSZ];
	struct tm datetm;

	if (cvs_nolog == 1)
		return;

	if (cvs_cmdop == CVS_OP_CHECKOUT || cvs_cmdop == CVS_OP_EXPORT) {
		if (type != CVS_HISTORY_CHECKOUT &&
		    type != CVS_HISTORY_EXPORT)
			return;
	}

	cvs_log(LP_TRACE, "cvs_history_add(`%c', `%s', `%s')",
	    historytab[type], (cf != NULL) ? cf->file_name : "", argument);

	/* construct repository field */
	if (cvs_cmdop != CVS_OP_CHECKOUT && cvs_cmdop != CVS_OP_EXPORT) {
		cvs_get_repository_name((cf != NULL) ? cf->file_wd : ".",
		    repo, sizeof(repo));
	} else {
		cvs_get_repository_name(argument, repo, sizeof(repo));
	}

	if (cvs_server_active == 1) {
		cwd = "<remote>";
	} else {
		if (getcwd(fpath, sizeof(fpath)) == NULL)
			fatal("cvs_history_add: getcwd: %s", strerror(errno));
		p = fpath;
		if (cvs_cmdop == CVS_OP_CHECKOUT ||
		    cvs_cmdop == CVS_OP_EXPORT) {
			if (strlcat(fpath, "/", sizeof(fpath)) >=
			    sizeof(fpath) || strlcat(fpath, argument,
			    sizeof(fpath)) >= sizeof(fpath))
				fatal("cvs_history_add: string truncation");
		}
		if (cvs_homedir != NULL && cvs_homedir[0] != '\0') {
			len = strlen(cvs_homedir);
			if (strncmp(cvs_homedir, fpath, len) == 0 &&
			    fpath[len] == '/') {
				p += len - 1;
				*p = '~';
			}
		}

		history_compress(p, repo);
		cwd = xstrdup(p);
	}

	/* construct revision field */
	revbuf[0] = '\0';
	rev = revbuf;
	switch (type) {
	case CVS_HISTORY_TAG:
		strlcpy(revbuf, argument, sizeof(revbuf));
		break;
	case CVS_HISTORY_CHECKOUT:
	case CVS_HISTORY_EXPORT:
		/*
		 * cvs_buf_alloc uses xcalloc(), so we are safe even
		 * if neither cvs_specified_tag nor cvs_specified_date
		 * have been supplied.
		 */
		buf = cvs_buf_alloc(128);
		if (cvs_specified_tag != NULL) {
			cvs_buf_puts(buf, cvs_specified_tag);
			if (cvs_specified_date != -1)
				cvs_buf_putc(buf, ':');
		}
		if (cvs_specified_date != -1) {
			gmtime_r(&cvs_specified_date, &datetm);
			strftime(timebuf, sizeof(timebuf),
			    "%Y.%m.%d.%H.%M.%S", &datetm);
			cvs_buf_puts(buf, timebuf);
		}
		rev = cvs_buf_release(buf);
		break;
	case CVS_HISTORY_UPDATE_MERGED:
	case CVS_HISTORY_UPDATE_MERGED_ERR:
	case CVS_HISTORY_COMMIT_MODIFIED:
	case CVS_HISTORY_COMMIT_ADDED:
	case CVS_HISTORY_COMMIT_REMOVED:
	case CVS_HISTORY_UPDATE_CO:
		if ((hrev = rcs_head_get(cf->file_rcs)) == NULL)
			fatal("cvs_history_add: rcs_head_get failed");
		rcsnum_tostr(hrev, revbuf, sizeof(revbuf));
		rcsnum_free(hrev);
		break;
	}

	(void)xsnprintf(fpath, sizeof(fpath), "%s/%s",
	    current_cvsroot->cr_dir, CVS_PATH_HISTORY);

	if ((fd = open(fpath, O_WRONLY|O_APPEND)) == -1) {
		if (errno != ENOENT)
			cvs_log(LP_ERR, "failed to open history file");
	} else {
		if ((fp = fdopen(fd, "a")) != NULL) {
			fprintf(fp, "%c%x|%s|%s|%s|%s|%s\n",
			    historytab[type], time(NULL), getlogin(), cwd,
			    repo, rev, (cf != NULL) ? cf->file_name :
			    argument);
			(void)fclose(fp);
		} else {
			cvs_log(LP_ERR, "failed to add entry to history file");
			(void)close(fd);
		}
	}

	if (rev != revbuf)
		xfree(rev);
	if (cvs_server_active != 1)
		xfree(cwd);
}
示例#22
0
void
cvs_parse_configfile(void)
{
	cvs_log(LP_TRACE, "cvs_parse_configfile()");
	cvs_read_config(CVS_PATH_CONFIG, config_parse_line);
}
示例#23
0
文件: add.c 项目: UNGLinux/Obase
void
cvs_add_tobranch(struct cvs_file *cf, char *tag)
{
	BUF *bp;
	char attic[MAXPATHLEN], repo[MAXPATHLEN];
	char *msg;
	struct stat st;
	RCSNUM *branch;

	cvs_log(LP_TRACE, "cvs_add_tobranch(%s)", cf->file_name);

	if (cvs_noexec == 1)
		return;

	if (fstat(cf->fd, &st) == -1)
		fatal("cvs_add_tobranch: %s", strerror(errno));

	cvs_get_repository_path(cf->file_wd, repo, MAXPATHLEN);
	(void)xsnprintf(attic, MAXPATHLEN, "%s/%s",
	    repo, CVS_PATH_ATTIC);

	if (mkdir(attic, 0755) == -1 && errno != EEXIST)
		fatal("cvs_add_tobranch: failed to create Attic");

	(void)xsnprintf(attic, MAXPATHLEN, "%s/%s/%s%s", repo,
	    CVS_PATH_ATTIC, cf->file_name, RCS_FILE_EXT);

	xfree(cf->file_rpath);
	cf->file_rpath = xstrdup(attic);

	cf->repo_fd = open(cf->file_rpath, O_CREAT|O_RDONLY);
	if (cf->repo_fd < 0)
		fatal("cvs_add_tobranch: %s: %s", cf->file_rpath,
		    strerror(errno));

	cf->file_rcs = rcs_open(cf->file_rpath, cf->repo_fd,
	    RCS_CREATE|RCS_WRITE, 0444);
	if (cf->file_rcs == NULL)
		fatal("cvs_add_tobranch: failed to create RCS file for %s",
		    cf->file_path);

	if ((branch = rcsnum_parse("1.1.2")) == NULL)
		fatal("cvs_add_tobranch: failed to parse branch");

	if (rcs_sym_add(cf->file_rcs, tag, branch) == -1)
		fatal("cvs_add_tobranch: failed to add vendor tag");

	(void)xasprintf(&msg, "file %s was initially added on branch %s.",
	    cf->file_name, tag);
	if (rcs_rev_add(cf->file_rcs, RCS_HEAD_REV, msg, -1, NULL) == -1)
		fatal("cvs_add_tobranch: failed to create first branch "
		    "revision");
	xfree(msg);

	if (rcs_findrev(cf->file_rcs, cf->file_rcs->rf_head) == NULL)
		fatal("cvs_add_tobranch: cannot find newly added revision");

	bp = buf_alloc(1);

	if (rcs_deltatext_set(cf->file_rcs,
	    cf->file_rcs->rf_head, bp) == -1)
		fatal("cvs_add_tobranch: failed to set deltatext");

	rcs_comment_set(cf->file_rcs, " * ");

	if (rcs_state_set(cf->file_rcs, cf->file_rcs->rf_head, RCS_STATE_DEAD)
	    == -1)
		fatal("cvs_add_tobranch: failed to set state");
}
示例#24
0
文件: add.c 项目: UNGLinux/Obase
static void
add_directory(struct cvs_file *cf)
{
	int added, nb;
	struct stat st;
	CVSENTRIES *entlist;
	char *date, entry[MAXPATHLEN], msg[1024], repo[MAXPATHLEN], *tag, *p;
	struct file_info_list files_info;
	struct file_info *fi;
	struct trigger_list *line_list;

	cvs_log(LP_TRACE, "add_directory(%s)", cf->file_path);

	(void)xsnprintf(entry, MAXPATHLEN, "%s%s",
	    cf->file_rpath, RCS_FILE_EXT);

	added = 1;
	if (stat(entry, &st) != -1) {
		cvs_log(LP_NOTICE, "cannot add directory %s: "
		    "a file with that name already exists",
		    cf->file_path);
		added = 0;
	} else {
		/* Let's see if we have any per-directory tags first. */
		cvs_parse_tagfile(cf->file_wd, &tag, &date, &nb);

		(void)xsnprintf(entry, MAXPATHLEN, "%s/%s",
		    cf->file_path, CVS_PATH_CVSDIR);

		if (cvs_server_active) {
			if (mkdir(cf->file_rpath, 0755) == -1 &&
			    errno != EEXIST)
				fatal("add_directory: %s: %s", cf->file_rpath,
				    strerror(errno));
		} else if (stat(entry, &st) != -1) {
			if (!S_ISDIR(st.st_mode)) {
				cvs_log(LP_ERR, "%s exists but is not "
				    "directory", entry);
			} else {
				cvs_log(LP_NOTICE, "%s already exists",
				    entry);
			}
			added = 0;
		} else if (cvs_noexec != 1) {
			if (mkdir(cf->file_rpath, 0755) == -1 &&
			    errno != EEXIST)
				fatal("add_directory: %s: %s", cf->file_rpath,
				    strerror(errno));

			cvs_get_repository_name(cf->file_wd, repo,
			    MAXPATHLEN);

			(void)xsnprintf(entry, MAXPATHLEN, "%s/%s",
			    repo, cf->file_name);

			cvs_mkadmin(cf->file_path, current_cvsroot->cr_dir,
			    entry, tag, date);

			p = xmalloc(CVS_ENT_MAXLINELEN);
			cvs_ent_line_str(cf->file_name, NULL, NULL, NULL,
			    NULL, 1, 0, p, CVS_ENT_MAXLINELEN);

			entlist = cvs_ent_open(cf->file_wd);
			cvs_ent_add(entlist, p);
			xfree(p);
		}
	}

	if (added == 1 && current_cvsroot->cr_method == CVS_METHOD_LOCAL) {
		(void)xsnprintf(msg, sizeof(msg),
		    "Directory %s added to the repository", cf->file_rpath);

		if (tag != NULL) {
			(void)strlcat(msg,
			    "\n--> Using per-directory sticky tag ",
			    sizeof(msg));
			(void)strlcat(msg, tag, sizeof(msg));
		}
		if (date != NULL) {
			(void)strlcat(msg,
			    "\n--> Using per-directory sticky date ",
			    sizeof(msg));
			(void)strlcat(msg, date, sizeof(msg));
		}
		cvs_printf("%s\n", msg);

		if (tag != NULL)
			xfree(tag);
		if (date != NULL)
			xfree(date);

		cvs_get_repository_name(cf->file_path, repo, MAXPATHLEN);
		line_list = cvs_trigger_getlines(CVS_PATH_LOGINFO, repo);
		if (line_list != NULL) {
			TAILQ_INIT(&files_info);
			fi = xcalloc(1, sizeof(*fi));
			fi->file_path = xstrdup(cf->file_path);
			TAILQ_INSERT_TAIL(&files_info, fi, flist);

			cvs_add_loginfo(repo);
			cvs_trigger_handle(CVS_TRIGGER_LOGINFO, repo,
			    loginfo, line_list, &files_info);

			cvs_trigger_freeinfo(&files_info);
			cvs_trigger_freelist(line_list);
			if (loginfo != NULL)
				xfree(loginfo);
		}
	}

	cf->file_status = FILE_SKIP;
}
示例#25
0
void
cvs_diff_local(struct cvs_file *cf)
{
	BUF *b1;
	int fd1, fd2;
	struct stat st;
	struct timespec tv[2], tv2[2];
	struct tm datetm;
	char rbuf[CVS_REV_BUFSZ], tbuf[CVS_TIME_BUFSZ], *p1, *p2;

	b1 = NULL;
	fd1 = fd2 = -1;
	p1 = p2 = NULL;

	cvs_log(LP_TRACE, "cvs_diff_local(%s)", cf->file_path);

	if (cf->file_type == CVS_DIR) {
		if (verbosity > 1)
			cvs_log(LP_ERR, "Diffing inside %s", cf->file_path);
		return;
	}

	cvs_file_classify(cf, cvs_directory_tag);

	if (cvs_cmdop == CVS_OP_DIFF) {
		if (cf->file_ent == NULL) {
			cvs_log(LP_ERR, "I know nothing about %s",
			    cf->file_path);
			return;
		}

		switch (cf->file_ent->ce_status) {
		case CVS_ENT_ADDED:
			if (Nflag == 0) {
				cvs_log(LP_ERR, "%s is a new entry, no "
				    "comparison available", cf->file_path);
				return;
			}
			if (!(cf->file_flags & FILE_ON_DISK)) {
				cvs_log(LP_ERR, "cannot find %s",
				    cf->file_path);
				return;
			}
			break;
		case CVS_ENT_REMOVED:
			if (Nflag == 0) {
				cvs_log(LP_ERR, "%s was removed, no "
				    "comparison available", cf->file_path);
				return;
			}
			if (cf->file_rcs == NULL) {
				cvs_log(LP_ERR, "cannot find RCS file for %s",
				    cf->file_path);
				return;
			}
			break;
		default:
			if (!(cf->file_flags & FILE_ON_DISK)) {
				cvs_printf("? %s\n", cf->file_path);
				return;
			}

			if (cf->file_rcs == NULL) {
				cvs_log(LP_ERR, "cannot find RCS file for %s",
				    cf->file_path);
				return;
			}
			break;
		}
	}

	if (cf->file_status == FILE_UPTODATE && rev1 == NULL && rev2 == NULL &&
	    date1 == -1 && date2 == -1)
		return;

	if (cf->file_rcs != NULL && cf->file_rcs->rf_head == NULL) {
		cvs_log(LP_ERR, "no head revision in RCS file for %s\n",
		    cf->file_path);
		return;
	}

	if (kflag && cf->file_rcs != NULL)
		rcs_kwexp_set(cf->file_rcs, kflag);

	if (cf->file_rcs == NULL)
		diff_rev1 = NULL;
	else if (rev1 != NULL || date1 != -1) {
		cvs_specified_date = date1;
		diff_rev1 = rcs_translate_tag(rev1, cf->file_rcs);
		if (diff_rev1 == NULL && cvs_cmdop == CVS_OP_DIFF) {
			if (rev1 != NULL) {
				cvs_log(LP_ERR, "tag %s not in file %s", rev1,
				    cf->file_path);
				goto cleanup;
			} else if (Nflag) {
				diff_rev1 = NULL;
			} else {
				gmtime_r(&cvs_specified_date, &datetm);
				strftime(tbuf, sizeof(tbuf),
				    "%Y.%m.%d.%H.%M.%S", &datetm);
				cvs_log(LP_ERR, "no revision for date %s in "
				    "file %s", tbuf, cf->file_path);
				goto cleanup;
			}
		} else if (diff_rev1 == NULL && cvs_cmdop == CVS_OP_RDIFF &&
		    force_head) {
			/* -f is not allowed for unknown symbols */
			if ((diff_rev1 = rcsnum_parse(rev1)) == NULL)
				fatal("no such tag %s", rev1);
			rcsnum_free(diff_rev1);

			diff_rev1 = cf->file_rcs->rf_head;
		}
		cvs_specified_date = -1;
	} else if (cvs_cmdop == CVS_OP_DIFF) {
		if (cf->file_ent->ce_status == CVS_ENT_ADDED)
			diff_rev1 = NULL;
		else
			diff_rev1 = cf->file_ent->ce_rev;
	}

	if (cf->file_rcs == NULL)
		diff_rev2 = NULL;
	else if (rev2 != NULL || date2 != -1) {
		cvs_specified_date = date2;
		diff_rev2 = rcs_translate_tag(rev2, cf->file_rcs);
		if (diff_rev2 == NULL && cvs_cmdop == CVS_OP_DIFF) {
			if (rev2 != NULL) {
				cvs_log(LP_ERR, "tag %s not in file %s", rev2,
				    cf->file_path);
				goto cleanup;
			} else if (Nflag) {
				diff_rev2 = NULL;
			} else {
				gmtime_r(&cvs_specified_date, &datetm);
				strftime(tbuf, sizeof(tbuf),
				    "%Y.%m.%d.%H.%M.%S", &datetm);
				cvs_log(LP_ERR, "no revision for date %s in "
				    "file %s", tbuf, cf->file_path);
				goto cleanup;
			}
		} else if (diff_rev2 == NULL && cvs_cmdop == CVS_OP_RDIFF &&
		    force_head) {
			/* -f is not allowed for unknown symbols */
			if ((diff_rev2 = rcsnum_parse(rev2)) == NULL)
				fatal("no such tag %s", rev2);
			rcsnum_free(diff_rev2);

			diff_rev2 = cf->file_rcs->rf_head;
		}
		cvs_specified_date = -1;
	} else if (cvs_cmdop == CVS_OP_RDIFF)
		diff_rev2 = cf->file_rcs->rf_head;
	else if (cf->file_ent->ce_status == CVS_ENT_REMOVED)
		diff_rev2 = NULL;

	if (diff_rev1 != NULL && diff_rev2 != NULL &&
	    rcsnum_cmp(diff_rev1, diff_rev2, 0) == 0)
		goto cleanup;

	switch (cvs_cmdop) {
	case CVS_OP_DIFF:
		if (cf->file_status == FILE_UPTODATE) {
			if (diff_rev2 == NULL &&
			    !rcsnum_cmp(diff_rev1, cf->file_rcsrev, 0))
				goto cleanup;
		}
		break;
	case CVS_OP_RDIFF:
		if (diff_rev1 == NULL && diff_rev2 == NULL)
			goto cleanup;
		break;
	}

	cvs_printf("Index: %s\n", cf->file_path);
	if (cvs_cmdop == CVS_OP_DIFF)
		cvs_printf("%s\nRCS file: %s\n", RCS_DIFF_DIV,
		    cf->file_rcs != NULL ? cf->file_rpath : cf->file_path);

	if (diff_rev1 != NULL) {
		if (cvs_cmdop == CVS_OP_DIFF && diff_rev1 != NULL) {
			(void)rcsnum_tostr(diff_rev1, rbuf, sizeof(rbuf));
			cvs_printf("retrieving revision %s\n", rbuf);
		}

		tv[0].tv_sec = rcs_rev_getdate(cf->file_rcs, diff_rev1);
		tv[0].tv_nsec = 0;
		tv[1] = tv[0];

		(void)xasprintf(&p1, "%s/diff1.XXXXXXXXXX", cvs_tmpdir);
		fd1 = rcs_rev_write_stmp(cf->file_rcs, diff_rev1, p1, 0);
		if (futimens(fd1, tv) == -1)
			fatal("cvs_diff_local: futimens failed");
	}

	if (diff_rev2 != NULL) {
		if (cvs_cmdop == CVS_OP_DIFF && rev2 != NULL) {
			(void)rcsnum_tostr(diff_rev2, rbuf, sizeof(rbuf));
			cvs_printf("retrieving revision %s\n", rbuf);
		}

		tv2[0].tv_sec = rcs_rev_getdate(cf->file_rcs, diff_rev2);
		tv2[0].tv_nsec = 0;
		tv2[1] = tv2[0];

		(void)xasprintf(&p2, "%s/diff2.XXXXXXXXXX", cvs_tmpdir);
		fd2 = rcs_rev_write_stmp(cf->file_rcs, diff_rev2, p2, 0);
		if (futimens(fd2, tv2) == -1)
			fatal("cvs_diff_local: futimens failed");
	} else if (cvs_cmdop == CVS_OP_DIFF &&
	    (cf->file_flags & FILE_ON_DISK) &&
	    cf->file_ent->ce_status != CVS_ENT_REMOVED) {
		(void)xasprintf(&p2, "%s/diff2.XXXXXXXXXX", cvs_tmpdir);
		if (cvs_server_active == 1 && cf->fd == -1) {
			tv2[0].tv_sec = rcs_rev_getdate(cf->file_rcs,
			    cf->file_ent->ce_rev);
			tv2[0].tv_nsec = 0;
			tv2[1] = tv2[0];

			fd2 = rcs_rev_write_stmp(cf->file_rcs,
			    cf->file_ent->ce_rev, p2, 0);
			if (futimens(fd2, tv2) == -1)
				fatal("cvs_diff_local: futimens failed");
		} else {
			if (fstat(cf->fd, &st) == -1)
				fatal("fstat failed %s", strerror(errno));
			b1 = buf_load_fd(cf->fd);

			tv2[0].tv_sec = st.st_mtime;
			tv2[0].tv_nsec = 0;
			tv2[1] = tv2[0];

			fd2 = buf_write_stmp(b1, p2, tv2);
			buf_free(b1);
		}
	}

	switch (cvs_cmdop) {
	case CVS_OP_DIFF:
		cvs_printf("%s", diffargs);

		if (rev1 != NULL && diff_rev1 != NULL) {
			(void)rcsnum_tostr(diff_rev1, rbuf, sizeof(rbuf));
			cvs_printf(" -r%s", rbuf);

			if (rev2 != NULL && diff_rev2 != NULL) {
				(void)rcsnum_tostr(diff_rev2, rbuf,
				    sizeof(rbuf));
				cvs_printf(" -r%s", rbuf);
			}
		}

		if (diff_rev2 == NULL)
			cvs_printf(" %s", cf->file_path);
		cvs_printf("\n");
		break;
	case CVS_OP_RDIFF:
		cvs_printf("diff ");
		switch (diff_format) {
		case D_CONTEXT:
			cvs_printf("-c ");
			break;
		case D_RCSDIFF:
			cvs_printf("-n ");
			break;
		case D_UNIFIED:
			cvs_printf("-u ");
			break;
		default:
			break;
		}
		if (diff_rev1 == NULL) {
			cvs_printf("%s ", CVS_PATH_DEVNULL);
		} else {
			(void)rcsnum_tostr(diff_rev1, rbuf, sizeof(rbuf));
			cvs_printf("%s:%s ", cf->file_path, rbuf);
		}

		if (diff_rev2 == NULL) {
			cvs_printf("%s:removed\n", cf->file_path);
		} else {
			(void)rcsnum_tostr(diff_rev2 != NULL ? diff_rev2 :
			    cf->file_rcs->rf_head, rbuf, sizeof(rbuf));
			cvs_printf("%s:%s\n", cf->file_path, rbuf);
		}
		break;
	}

	if (fd1 == -1) {
		if ((fd1 = open(CVS_PATH_DEVNULL, O_RDONLY, 0)) == -1)
			fatal("cannot open %s", CVS_PATH_DEVNULL);
	}
	if (fd2 == -1) {
		if ((fd2 = open(CVS_PATH_DEVNULL, O_RDONLY, 0)) == -1)
			fatal("cannot open %s", CVS_PATH_DEVNULL);
	}

	if (diffreg(p1 != NULL ? cf->file_path : CVS_PATH_DEVNULL,
	    p2 != NULL ? cf->file_path : CVS_PATH_DEVNULL, fd1, fd2, NULL,
	    dflags) == D_ERROR)
		fatal("cvs_diff_local: failed to get RCS patch");

	close(fd1);
	close(fd2);

	worklist_run(&temp_files, worklist_unlink);

	if (p1 != NULL)
		xfree(p1);
	if (p2 != NULL)
		xfree(p2);

cleanup:
	if (diff_rev1 != NULL &&
	    (cf->file_rcs == NULL || diff_rev1 != cf->file_rcs->rf_head) &&
	    (cf->file_ent == NULL || diff_rev1 != cf->file_ent->ce_rev))
		xfree(diff_rev1);
	diff_rev1 = NULL;

	if (diff_rev2 != NULL &&
	    (cf->file_rcs == NULL || diff_rev2 != cf->file_rcs->rf_head))
		xfree(diff_rev2);
	diff_rev2 = NULL;
}
示例#26
0
void
cvs_annotate_local(struct cvs_file *cf)
{
	int i;
	char date[10], rnum[13], *p;
	RCSNUM *bnum, *rev;
	struct rcs_line *line;
	struct rcs_line **alines;

	cvs_log(LP_TRACE, "cvs_annotate_local(%s)", cf->file_path);

	cvs_file_classify(cf, cvs_directory_tag);

	if (cf->file_rcs == NULL || cf->file_rcs->rf_head == NULL)
		return;

	if (cvs_specified_tag != NULL) {
		if ((rev = rcs_translate_tag(cvs_specified_tag,
		    cf->file_rcs)) == NULL) {
			if (!force_head)
				/* Stick at weird GNU cvs, ignore error. */
				return;

			/* -f is not allowed for unknown symbols */
			rev = rcsnum_parse(cvs_specified_tag);
			if (rev == NULL)
				fatal("no such tag %s", cvs_specified_tag);
                        rcsnum_free(rev);
			rev = rcsnum_alloc();
			rcsnum_cpy(cf->file_rcs->rf_head, rev, 0);
		}

		/*
		 * If this is a revision in a branch, we have to go first
		 * from HEAD to branch, then down to 1.1. After that, take
		 * annotated branch and go up to branch revision. This must
		 * be done this way due to different handling of "a" and
		 * "d" in rcs file for annotation.
		 */
		if (!RCSNUM_ISBRANCHREV(rev)) {
			bnum = rev;
		} else {
			bnum = rcsnum_alloc();
			rcsnum_cpy(rev, bnum, 2);
		}

		rcs_rev_getlines(cf->file_rcs, bnum, &alines);

		/*
		 * Go into branch and receive annotations for branch revision,
		 * with inverted "a" and "d" meaning.
		 */
		if (bnum != rev) {
			rcs_annotate_getlines(cf->file_rcs, rev, &alines);
			rcsnum_free(bnum);
		}
		rcsnum_free(rev);
	} else {
		rcs_rev_getlines(cf->file_rcs, (cvs_specified_date != -1 ||
		    cvs_directory_date != -1) ? cf->file_rcsrev :
		    cf->file_rcs->rf_head, &alines);
	}

	/* Stick at weird GNU cvs, ignore error. */
	if (alines == NULL)
		return;

	cvs_log(LP_RCS, "Annotations for %s", cf->file_path);
	cvs_log(LP_RCS, "***************");

	for (i = 0; alines[i] != NULL; i++) {
		line = alines[i];

		rcsnum_tostr(line->l_delta->rd_num, rnum, sizeof(rnum));
		strftime(date, sizeof(date), "%d-%b-%y",
		    &(line->l_delta->rd_date));
		if (line->l_len && line->l_line[line->l_len - 1] == '\n')
			line->l_line[line->l_len - 1] = '\0';
		else {
			p = xmalloc(line->l_len + 1);
			memcpy(p, line->l_line, line->l_len);
			p[line->l_len] = '\0';

			if (line->l_needsfree)
				xfree(line->l_line);
			line->l_line = p;
			line->l_len++;
			line->l_needsfree = 1;
		}
		cvs_printf("%-12.12s (%-8.8s %s): %s\n", rnum,
		    line->l_delta->rd_author, date, line->l_line);

		if (line->l_needsfree)
			xfree(line->l_line);
		xfree(line);
	}

	xfree(alines);
}
示例#27
0
struct trigger_list *
cvs_trigger_getlines(char * file, char * repo)
{
	FILE *fp;
	int allow_all, lineno, match = 0;
	size_t len;
	regex_t preg;
	struct trigger_list *list;
	struct trigger_line *tline;
	char fpath[PATH_MAX];
	char *currentline, *defaultline = NULL, *nline, *p, *q, *regex;

	if (strcmp(file, CVS_PATH_EDITINFO) == 0 ||
	    strcmp(file, CVS_PATH_VERIFYMSG) == 0)
		allow_all = 0;
	else
		allow_all = 1;

	(void)xsnprintf(fpath, PATH_MAX, "%s/%s", current_cvsroot->cr_dir,
	    file);

	if ((fp = fopen(fpath, "r")) == NULL) {
		if (errno != ENOENT)
			cvs_log(LP_ERRNO, "cvs_trigger_getlines: %s", file);
		return (NULL);
	}

	list = xmalloc(sizeof(*list));
	TAILQ_INIT(list);
	
	lineno = 0;
	nline = NULL;
	while ((currentline = fgetln(fp, &len)) != NULL) {
		if (currentline[len - 1] == '\n') {
			currentline[len - 1] = '\0';
		} else {
			nline = xmalloc(len + 1);
			memcpy(nline, currentline, len);
			nline[len] = '\0';
			currentline = nline;
		}

		lineno++;

		for (p = currentline; isspace((unsigned char)*p); p++)
			;

		if (*p == '\0' || *p == '#')
			continue;

		for (q = p; !isspace((unsigned char)*q) && *q != '\0'; q++)
			;

		if (*q == '\0')
			goto bad;

		*q++ = '\0';
		regex = p;

		for (; isspace((unsigned char)*q); q++)
			;

		if (*q == '\0')
			goto bad;

		if (strcmp(regex, "ALL") == 0 && allow_all) {
			tline = xmalloc(sizeof(*tline));
			tline->line = xstrdup(q);
			TAILQ_INSERT_TAIL(list, tline, flist);
		} else if (defaultline == NULL && !match &&
		    strcmp(regex, "DEFAULT") == 0) {
			defaultline = xstrdup(q);
		} else if (!match) {
			if (regcomp(&preg, regex, REG_NOSUB|REG_EXTENDED))
				goto bad;

			if (regexec(&preg, repo, 0, NULL, 0) != REG_NOMATCH) {
				match = 1;

				tline = xmalloc(sizeof(*tline));
				tline->line = xstrdup(q);
				TAILQ_INSERT_HEAD(list, tline, flist);
			}
			regfree(&preg);
		}
	}

	free(nline);

	if (defaultline != NULL) {
		if (!match) {
			tline = xmalloc(sizeof(*tline));
			tline->line = defaultline;
			TAILQ_INSERT_HEAD(list, tline, flist);
		} else
			free(defaultline);
	}

	(void)fclose(fp);
	
	if (TAILQ_EMPTY(list)) {
		free(list);
		list = NULL;
	}

	return (list);

bad:
	cvs_log(LP_NOTICE, "%s: malformed line %d", file, lineno);
	free(defaultline);
	cvs_trigger_freelist(list);

	(void)fclose(fp);
	
	return (NULL);
}
示例#28
0
int
cvs_diff(int argc, char **argv)
{
	int ch, flags;
	char *arg = ".";
	const char *errstr;
	struct cvs_recursion cr;

	flags = CR_RECURSE_DIRS;
	strlcpy(diffargs, cvs_cmdop == CVS_OP_DIFF ? "diff" : "rdiff",
	    sizeof(diffargs));

	while ((ch = getopt(argc, argv, cvs_cmdop == CVS_OP_DIFF ?
	    cvs_cmd_diff.cmd_opts : cvs_cmd_rdiff.cmd_opts)) != -1) {
		switch (ch) {
		case 'a':
			strlcat(diffargs, " -a", sizeof(diffargs));
			dflags |= D_FORCEASCII;
			break;
		case 'b':
			strlcat(diffargs, " -b", sizeof(diffargs));
			dflags |= D_FOLDBLANKS;
			break;
		case 'c':
			strlcat(diffargs, " -c", sizeof(diffargs));
			diff_format = D_CONTEXT;
			break;
		case 'C':
			diff_context = strtonum(optarg, 0, INT_MAX, &errstr);
			if (errstr != NULL)
				fatal("context lines %s: %s", errstr, optarg);
			strlcat(diffargs, " -C ", sizeof(diffargs));
			strlcat(diffargs, optarg, sizeof(diffargs));
			diff_format = D_CONTEXT;
			break;
		case 'd':
			strlcat(diffargs, " -d", sizeof(diffargs));
			dflags |= D_MINIMAL;
			break;
		case 'D':
			if (date1 == -1 && rev1 == NULL) {
				if ((date1 = date_parse(optarg)) == -1)
					fatal("invalid date: %s", optarg);
				dateflag1 = optarg;
			} else if (date2 == -1 && rev2 == NULL) {
				if ((date2 = date_parse(optarg)) == -1)
					fatal("invalid date: %s", optarg);
				dateflag2 = optarg;
			} else {
				fatal("no more than 2 revisions/dates can"
				    " be specified");
			}
			break;
		case 'f':
			force_head = 1;
			break;
		case 'i':
			strlcat(diffargs, " -i", sizeof(diffargs));
			dflags |= D_IGNORECASE;
			break;
		case 'k':
			koptstr = optarg;
			kflag = rcs_kflag_get(koptstr);
			if (RCS_KWEXP_INVAL(kflag)) {
				cvs_log(LP_ERR,
				    "invalid RCS keyword expansion mode");
				fatal("%s", cvs_cmdop == CVS_OP_DIFF ?
				    cvs_cmd_diff.cmd_synopsis :
				    cvs_cmd_rdiff.cmd_synopsis);
			}
			break;
		case 'l':
			flags &= ~CR_RECURSE_DIRS;
			break;
		case 'n':
			strlcat(diffargs, " -n", sizeof(diffargs));
			diff_format = D_RCSDIFF;
			break;
		case 'N':
			strlcat(diffargs, " -N", sizeof(diffargs));
			Nflag = 1;
			break;
		case 'p':
			strlcat(diffargs, " -p", sizeof(diffargs));
			dflags |= D_PROTOTYPE;
			break;
		case 'R':
			flags |= CR_RECURSE_DIRS;
			break;
		case 'r':
			if (date1 == -1 && rev1 == NULL) {
				rev1 = optarg;
			} else if (date2 == -1 && rev2 == NULL) {
				rev2 = optarg;
			} else {
				fatal("no more than 2 revisions/dates can"
				    " be specified");
			}
			break;
		case 't':
			strlcat(diffargs, " -t", sizeof(diffargs));
			dflags |= D_EXPANDTABS;
			break;
		case 'u':
			strlcat(diffargs, " -u", sizeof(diffargs));
			diff_format = D_UNIFIED;
			break;
		case 'U':
			diff_context = strtonum(optarg, 0, INT_MAX, &errstr);
			if (errstr != NULL)
				fatal("context lines %s: %s", errstr, optarg);
			strlcat(diffargs, " -U ", sizeof(diffargs));
			strlcat(diffargs, optarg, sizeof(diffargs));
			diff_format = D_UNIFIED;
			break;
		case 'V':
			fatal("the -V option is obsolete "
			    "and should not be used");
		case 'w':
			strlcat(diffargs, " -w", sizeof(diffargs));
			dflags |= D_IGNOREBLANKS;
			break;
		default:
			fatal("%s", cvs_cmdop == CVS_OP_DIFF ?
			    cvs_cmd_diff.cmd_synopsis :
			    cvs_cmd_rdiff.cmd_synopsis);
		}
	}

	argc -= optind;
	argv += optind;

	cr.enterdir = NULL;
	cr.leavedir = NULL;

	if (cvs_cmdop == CVS_OP_RDIFF) {
		if (rev1 == NULL && rev2 == NULL && dateflag1 == NULL &&
		    dateflag2 == NULL)
			fatal("must specify at least one revision/date!");

		if (!argc)
			fatal("%s", cvs_cmd_rdiff.cmd_synopsis);

		if (!diff_format) {
			strlcat(diffargs, " -c", sizeof(diffargs));
			diff_format = D_CONTEXT;
		}

		flags |= CR_REPO;
	}

	if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
		cvs_client_connect_to_server();
		cr.fileproc = cvs_client_sendfile;

		if (!(flags & CR_RECURSE_DIRS))
			cvs_client_send_request("Argument -l");

		if (kflag)
			cvs_client_send_request("Argument -k%s", koptstr);

		switch (diff_format) {
		case D_CONTEXT:
			if (cvs_cmdop == CVS_OP_RDIFF)
				cvs_client_send_request("Argument -c");
			else {
				cvs_client_send_request("Argument -C %d",
				    diff_context);
			}
			break;
		case D_RCSDIFF:
			cvs_client_send_request("Argument -n");
			break;
		case D_UNIFIED:
			if (cvs_cmdop == CVS_OP_RDIFF || diff_context == 3)
				cvs_client_send_request("Argument -u");
			else {
				cvs_client_send_request("Argument -U %d",
				    diff_context);
			}
			break;
		default:
			break;
		}

		if (Nflag == 1)
			cvs_client_send_request("Argument -N");

		if (dflags & D_PROTOTYPE)
			cvs_client_send_request("Argument -p");

		if (rev1 != NULL)
			cvs_client_send_request("Argument -r%s", rev1);
		if (rev2 != NULL)
			cvs_client_send_request("Argument -r%s", rev2);

		if (dateflag1 != NULL)
			cvs_client_send_request("Argument -D%s", dateflag1);
		if (dateflag2 != NULL)
			cvs_client_send_request("Argument -D%s", dateflag2);
	} else {
		if (cvs_cmdop == CVS_OP_RDIFF &&
		    chdir(current_cvsroot->cr_dir) == -1)
			fatal("cvs_diff: %s", strerror(errno));

		cr.fileproc = cvs_diff_local;
	}

	cr.flags = flags;

	diff_rev1 = diff_rev2 = NULL;

	if (cvs_cmdop == CVS_OP_DIFF ||
	    current_cvsroot->cr_method == CVS_METHOD_LOCAL) {
		if (argc > 0)
			cvs_file_run(argc, argv, &cr);
		else
			cvs_file_run(1, &arg, &cr);
	}

	if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
		cvs_client_send_files(argv, argc);
		cvs_client_senddir(".");

		cvs_client_send_request((cvs_cmdop == CVS_OP_RDIFF) ?
		    "rdiff" : "diff");

		cvs_client_get_responses();
	}

	return (0);
}
示例#29
0
文件: admin.c 项目: UNGLinux/Obase
int
cvs_admin(int argc, char **argv)
{
	int ch;
	int flags;
	char *statestr;
	struct cvs_recursion cr;

	flags = CR_RECURSE_DIRS;

	alist = comment = elist = logmsg = logstr = NULL;
	oldfilename = orange = state = statestr = NULL;

	while ((ch = getopt(argc, argv, cvs_cmd_admin.cmd_opts)) != -1) {
		switch (ch) {
		case 'A':
			oldfilename = optarg;
			break;
		case 'a':
			alist = optarg;
			break;
		case 'b':
			break;
		case 'c':
			comment = optarg;
			break;
		case 'e':
			elist = optarg;
			runflags |= ADM_EFLAG;
			break;
		case 'I':
			break;
		case 'k':
			koptstr = optarg;
			kflag = rcs_kflag_get(koptstr);
			if (RCS_KWEXP_INVAL(kflag)) {
				cvs_log(LP_ERR,
				    "invalid RCS keyword expansion mode");
				fatal("%s", cvs_cmd_admin.cmd_synopsis);
			}
			break;
		case 'L':
			if (lkmode == RCS_LOCK_LOOSE) {
				cvs_log(LP_ERR, "-L and -U are incompatible");
				fatal("%s", cvs_cmd_admin.cmd_synopsis);
			}
			lkmode = RCS_LOCK_STRICT;
			break;
		case 'l':
			break;
		case 'm':
			logstr = optarg;
			break;
		case 'N':
			break;
		case 'n':
			break;
		case 'o':
			orange = optarg;
			break;
		case 'q':
			verbosity = 0;
			break;
		case 's':
			statestr = optarg;
			break;
		case 't':
			break;
		case 'U':
			if (lkmode == RCS_LOCK_STRICT) {
				cvs_log(LP_ERR, "-U and -L are incompatible");
				fatal("%s", cvs_cmd_admin.cmd_synopsis);
			}
			lkmode = RCS_LOCK_LOOSE;
			break;
		case 'u':
			break;
		default:
			fatal("%s", cvs_cmd_admin.cmd_synopsis);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc == 0)
		fatal("%s", cvs_cmd_admin.cmd_synopsis);

	cr.enterdir = NULL;
	cr.leavedir = NULL;

	if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
		cvs_client_connect_to_server();
		cr.fileproc = cvs_client_sendfile;

		if (oldfilename != NULL)
			cvs_client_send_request("Argument -A%s", oldfilename);

		if (alist != NULL)
			cvs_client_send_request("Argument -a%s", alist);

		if (comment != NULL)
			cvs_client_send_request("Argument -c%s", comment);

		if (runflags & ADM_EFLAG)
			cvs_client_send_request("Argument -e%s",
			    (elist != NULL) ? elist : "");

		if (koptstr != NULL)
			cvs_client_send_request("Argument -k%s", koptstr);

		if (lkmode == RCS_LOCK_STRICT)
			cvs_client_send_request("Argument -L");
		else if (lkmode == RCS_LOCK_LOOSE)
			cvs_client_send_request("Argument -U");

		if (logstr != NULL)
			cvs_client_send_logmsg(logstr);

		if (orange != NULL)
			cvs_client_send_request("Argument -o%s", orange);

		if (statestr != NULL)
			cvs_client_send_request("Argument -s%s", statestr);

		if (verbosity == 0)
			cvs_client_send_request("Argument -q");

	} else {
		if (statestr != NULL) {
			if ((staterevstr = strchr(statestr, ':')) != NULL)
				*staterevstr++ = '\0';
			state = statestr;
			if (rcs_state_check(state) < 0) {
				cvs_log(LP_ERR, "invalid state `%s'", state);
				state = NULL;
			}
		}

		flags |= CR_REPO;
		cr.fileproc = cvs_admin_local;
	}

	cr.flags = flags;

	cvs_file_run(argc, argv, &cr);

	if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
		cvs_client_send_files(argv, argc);
		cvs_client_senddir(".");
		cvs_client_send_request("admin");
		cvs_client_get_responses();
	}

	return (0);
}
示例#30
0
文件: add.c 项目: UNGLinux/Obase
static void
add_file(struct cvs_file *cf)
{
	int nb, stop;
	char revbuf[CVS_REV_BUFSZ];
	RCSNUM *head = NULL;
	char *tag;

	cvs_parse_tagfile(cf->file_wd, &tag, NULL, &nb);
	if (nb) {
		cvs_log(LP_ERR, "cannot add file on non-branch tag %s", tag);
		return;
	}

	if (cf->file_rcs != NULL) {
		head = rcs_head_get(cf->file_rcs);
		if (head == NULL) {
			cvs_log(LP_NOTICE, "no head revision in RCS file for "
			    "%s", cf->file_path);
		}
		rcsnum_tostr(head, revbuf, sizeof(revbuf));
	}

	stop = 0;
	switch (cf->file_status) {
	case FILE_ADDED:
	case FILE_CHECKOUT:
		if (verbosity > 1)
			cvs_log(LP_NOTICE, "%s has already been entered",
			    cf->file_path);
		stop = 1;
		break;
	case FILE_REMOVED:
		if (cf->file_rcs == NULL) {
			cvs_log(LP_NOTICE, "cannot resurrect %s; "
			    "RCS file removed by second party", cf->file_name);
		} else if (!(cf->file_flags & FILE_ON_DISK)) {
			add_entry(cf);

			/* Restore the file. */
			cvs_checkout_file(cf, head, NULL, 0);

			cvs_printf("U %s\n", cf->file_path);

			cvs_log(LP_NOTICE, "%s, version %s, resurrected",
			    cf->file_name, revbuf);

			cf->file_status = FILE_UPTODATE;
		}
		stop = 1;
		break;
	case FILE_CONFLICT:
	case FILE_LOST:
	case FILE_MODIFIED:
	case FILE_UPTODATE:
		if (cf->file_rcs != NULL && cf->file_rcs->rf_dead == 0) {
			cvs_log(LP_NOTICE, "%s already exists, with version "
			     "number %s", cf->file_path, revbuf);
			stop = 1;
		}
		break;
	case FILE_UNKNOWN:
		if (cf->file_rcs != NULL && cf->file_rcs->rf_dead == 1) {
			cvs_log(LP_NOTICE, "re-adding file %s "
			    "(instead of dead revision %s)",
			    cf->file_path, revbuf);
			added_files++;
		} else if (cf->file_flags & FILE_ON_DISK) {
			cvs_log(LP_NOTICE, "scheduling file '%s' for addition",
			    cf->file_path);
			added_files++;
		} else {
			stop = 1;
		}
		break;
	default:
		break;
	}

	if (head != NULL)
		rcsnum_free(head);

	if (stop == 1)
		return;

	add_entry(cf);
}