diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/cvs/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/cvs/cmd.c | 4 | ||||
-rw-r--r-- | usr.bin/cvs/cvs.c | 7 | ||||
-rw-r--r-- | usr.bin/cvs/cvs.h | 4 | ||||
-rw-r--r-- | usr.bin/cvs/init.c | 241 | ||||
-rw-r--r-- | usr.bin/cvs/init.h | 31 |
6 files changed, 190 insertions, 101 deletions
diff --git a/usr.bin/cvs/Makefile b/usr.bin/cvs/Makefile index 73dcef8ff12..5f7582413e5 100644 --- a/usr.bin/cvs/Makefile +++ b/usr.bin/cvs/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.28 2006/06/07 18:19:07 xsa Exp $ +# $OpenBSD: Makefile,v 1.29 2006/06/12 13:56:00 xsa Exp $ PROG= opencvs MAN= cvs.1 cvsignore.5 cvsrc.5 cvswrappers.5 cvsintro.7 @@ -6,7 +6,7 @@ CPPFLAGS+=-I${.CURDIR} SRCS= cvs.c add.c commit.c config.c checkout.c buf.c cmd.c date.y diff.c \ diff3.c diff_internals.c entries.c fatal.c file.c getlog.c log.c \ - import.c remove.c repository.c rcs.c rcsnum.c rcstime.c root.c \ + import.c init.c remove.c repository.c rcs.c rcsnum.c rcstime.c root.c \ status.c tag.c worklist.c util.c update.c xmalloc.c CFLAGS+=-Wall diff --git a/usr.bin/cvs/cmd.c b/usr.bin/cvs/cmd.c index 983f8bfb474..b6304e81fbf 100644 --- a/usr.bin/cvs/cmd.c +++ b/usr.bin/cvs/cmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd.c,v 1.50 2006/06/07 18:19:07 xsa Exp $ */ +/* $OpenBSD: cmd.c,v 1.51 2006/06/12 13:56:00 xsa Exp $ */ /* * Copyright (c) 2005 Joris Vink <joris@openbsd.org> * All rights reserved. @@ -38,6 +38,7 @@ struct cvs_cmd *cvs_cdt[] = { &cvs_cmd_diff, &cvs_cmd_export, &cvs_cmd_import, + &cvs_cmd_init, &cvs_cmd_log, &cvs_cmd_remove, &cvs_cmd_status, @@ -50,7 +51,6 @@ struct cvs_cmd *cvs_cdt[] = { &cvs_cmd_edit, &cvs_cmd_editors, &cvs_cmd_history, - &cvs_cmd_init, #if 0 &cvs_cmd_login, &cvs_cmd_logout, diff --git a/usr.bin/cvs/cvs.c b/usr.bin/cvs/cvs.c index b4092587780..920a5148b78 100644 --- a/usr.bin/cvs/cvs.c +++ b/usr.bin/cvs/cvs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cvs.c,v 1.102 2006/06/02 19:10:23 david Exp $ */ +/* $OpenBSD: cvs.c,v 1.103 2006/06/12 13:56:00 xsa Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> @@ -228,7 +228,7 @@ main(int argc, char **argv) i = snprintf(fpath, sizeof(fpath), "%s/%s", current_cvsroot->cr_dir, CVS_PATH_ROOT); - if (stat(fpath, &st) == -1) { + if (stat(fpath, &st) == -1 && cvs_cmdop != CVS_OP_INIT) { if (errno == ENOENT) fatal("'%s' does not seem to be a valid repository", current_cvsroot->cr_dir); @@ -241,7 +241,8 @@ main(int argc, char **argv) current_cvsroot->cr_dir); } - cvs_parse_configfile(); + if (cvs_cmdop != CVS_OP_INIT) + cvs_parse_configfile(); umask(cvs_umask); diff --git a/usr.bin/cvs/cvs.h b/usr.bin/cvs/cvs.h index a3491a60a66..5c143b24b37 100644 --- a/usr.bin/cvs/cvs.h +++ b/usr.bin/cvs/cvs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cvs.h,v 1.111 2006/06/03 19:07:13 joris Exp $ */ +/* $OpenBSD: cvs.h,v 1.112 2006/06/12 13:56:00 xsa Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -108,6 +108,7 @@ #define CVS_PATH_DEVNULL "/dev/null" #define CVS_PATH_ROOT "CVSROOT" #define CVS_PATH_EMPTYDIR CVS_PATH_ROOT "/Emptydir" +#define CVS_PATH_CHECKOUTLIST CVS_PATH_ROOT "/checkoutlist" #define CVS_PATH_COMMITINFO CVS_PATH_ROOT "/commitinfo" #define CVS_PATH_CONFIG CVS_PATH_ROOT "/config" #define CVS_PATH_CVSIGNORE CVS_PATH_ROOT "/cvsignore" @@ -119,6 +120,7 @@ #define CVS_PATH_NOTIFY_R CVS_PATH_ROOT "/notify" #define CVS_PATH_RCSINFO CVS_PATH_ROOT "/rcsinfo" #define CVS_PATH_TAGINFO CVS_PATH_ROOT "/taginfo" +#define CVS_PATH_VALTAGS CVS_PATH_ROOT "/val-tags" #define CVS_PATH_VERIFYMSG CVS_PATH_ROOT "/verifymsg" /* client-side paths */ diff --git a/usr.bin/cvs/init.c b/usr.bin/cvs/init.c index 2c465f198c2..f58b9bd27ab 100644 --- a/usr.bin/cvs/init.c +++ b/usr.bin/cvs/init.c @@ -1,6 +1,7 @@ -/* $OpenBSD: init.c,v 1.22 2006/02/10 10:15:48 xsa Exp $ */ +/* $OpenBSD: init.c,v 1.23 2006/06/12 13:56:00 xsa Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> + * Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,37 +28,43 @@ #include "includes.h" #include "cvs.h" +#include "init.h" #include "log.h" #include "proto.h" +int cvs_init(int, char **); +void cvs_init_local(void); -#define CFT_FILE 1 -#define CFT_DIR 2 - +static void init_mkdir(const char *, mode_t); +static void init_mkfile(char *, const char *const *); struct cvsroot_file { - char *cf_path; /* path relative to CVS root directory */ - u_int cf_type; - mode_t cf_mode; -} cvsroot_files[] = { - { CVS_PATH_ROOT, CFT_DIR, (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) }, - { CVS_PATH_EMPTYDIR, CFT_DIR, (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) }, - { CVS_PATH_COMMITINFO, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) }, - { CVS_PATH_CONFIG, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) }, - { CVS_PATH_CVSIGNORE, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) }, - { CVS_PATH_CVSWRAPPERS, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) }, - { CVS_PATH_EDITINFO, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) }, - { CVS_PATH_HISTORY, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) }, - { CVS_PATH_LOGINFO, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) }, - { CVS_PATH_MODULES, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) }, - { CVS_PATH_NOTIFY_R, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) }, - { CVS_PATH_RCSINFO, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) }, - { CVS_PATH_TAGINFO, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) }, - { CVS_PATH_VERIFYMSG, CFT_FILE, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) }, + char *cf_path; + const char *const *cf_content; +}; + +static const struct cvsroot_file cvsroot_files[] = { + { CVS_PATH_CHECKOUTLIST, NULL }, + { CVS_PATH_COMMITINFO, NULL }, + { CVS_PATH_CONFIG, config_contents }, + { CVS_PATH_CVSWRAPPERS, NULL }, + { CVS_PATH_EDITINFO, NULL }, + { CVS_PATH_HISTORY, NULL }, + { CVS_PATH_LOGINFO, NULL }, + { CVS_PATH_MODULES, NULL }, + { CVS_PATH_NOTIFY_R, NULL }, + { CVS_PATH_RCSINFO, NULL }, + { CVS_PATH_TAGINFO, NULL }, + { CVS_PATH_VALTAGS, NULL }, + { CVS_PATH_VERIFYMSG, NULL } }; -static int cvs_init_pre_exec(struct cvsroot *); -static void cvs_init_create_files(struct cvsroot *); +static const char *cvsroot_dirs[2] = { + CVS_PATH_ROOT, CVS_PATH_EMPTYDIR +}; + +#define INIT_NFILES (sizeof(cvsroot_files)/sizeof(cvsroot_files[0])) +#define INIT_NDIRS (sizeof(cvsroot_dirs)/sizeof(cvsroot_dirs[0])) struct cvs_cmd cvs_cmd_init = { CVS_OP_INIT, CVS_REQ_INIT, "init", @@ -66,89 +73,137 @@ struct cvs_cmd cvs_cmd_init = { "", "", NULL, - 0, - NULL, - cvs_init_pre_exec, - NULL, - NULL, - NULL, - NULL, - 0 + cvs_init }; -/* - * cvs_init_pre_exec() - * - * Local/remote handler for the "cvs init" command. - * Returns 0 on success, -1 on failure. - */ -static int -cvs_init_pre_exec(struct cvsroot *root) +int +cvs_init(int argc, char **argv) { - if (root->cr_method == CVS_METHOD_LOCAL) - cvs_init_create_files(root); + if (argc > 1) + fatal("%s", cvs_cmd_init.cmd_synopsis); + + if (current_cvsroot->cr_method == CVS_METHOD_LOCAL) + cvs_init_local(); return (0); } -/* - * cvs_init_create_files - * - * Create all required files for the "cvs init" command. - * Used by the local handlers. - * Returns 0 on success, -1 on failure. - * - */ -static void -cvs_init_create_files(struct cvsroot *root) +void +cvs_init_local(void) { - size_t len; - int fd; u_int i; - char path[MAXPATHLEN]; - RCSFILE *rfp; - struct stat st; + char *path; + + cvs_log(LP_TRACE, "cvs_init_local()"); /* Create repository root directory if it does not already exist */ - if (mkdir(root->cr_dir, 0777) == -1) { - if (!(errno == EEXIST || (errno == EACCES && - (stat(root->cr_dir, &st) == 0) && S_ISDIR(st.st_mode)))) { - fatal("cvs_init_create_files: mkdir: %s: %s", - root->cr_dir, strerror(errno)); + init_mkdir(current_cvsroot->cr_dir, 0777); + + path = xmalloc(MAXPATHLEN); + + for (i = 0; i < INIT_NDIRS; i++) { + if (cvs_path_cat(current_cvsroot->cr_dir, + cvsroot_dirs[i], path, MAXPATHLEN) >= MAXPATHLEN) + fatal("cvs_init_local: truncation"); + + init_mkdir(path, 0777); + } + + for (i = 0; i < INIT_NFILES; i++) { + if (cvs_path_cat(current_cvsroot->cr_dir, + cvsroot_files[i].cf_path, path, MAXPATHLEN) >= MAXPATHLEN) + fatal("cvs_init_local: truncation"); + + init_mkfile(path, cvsroot_files[i].cf_content); + } + + xfree(path); +} + +static void +init_mkdir(const char *path, mode_t mode) +{ + struct stat st; + + if (mkdir(path, mode) == -1) { + if (!(errno == EEXIST || + (errno == EACCES && (stat(path, &st) == 0) && + S_ISDIR(st.st_mode)))) { + fatal("init_mkdir: mkdir: `%s': %s", + path, strerror(errno)); } } +} + +static void +init_mkfile(char *path, const char *const *content) +{ + BUF *b; + size_t len; + int fd, openflags, rcsflags; + char *d, *rpath; + const char *const *p; + RCSFILE *file; + + len = 0; + fd = -1; + d = NULL; + openflags = O_WRONLY|O_CREAT|O_EXCL; + rcsflags = RCS_RDWR|RCS_CREATE; - /* Create the repository administrative files */ - for (i = 0; i < sizeof(cvsroot_files)/sizeof(cvsroot_files[i]); i++) { - len = cvs_path_cat(root->cr_dir, cvsroot_files[i].cf_path, - path, sizeof(path)); - if (len >= sizeof(path)) - fatal("cvs_init_create_files: path truncation"); - - if (cvsroot_files[i].cf_type == CFT_DIR) { - if (mkdir(path, cvsroot_files[i].cf_mode) == -1) { - if (!(errno == EEXIST || (errno == EACCES && - (stat(path, &st) == 0) && - S_ISDIR(st.st_mode)))) { - fatal("cvs_init_create_files: mkdir: " - "%s: %s", path, strerror(errno)); - } - } - } else if (cvsroot_files[i].cf_type == CFT_FILE) { - fd = open(path, O_WRONLY|O_CREAT|O_EXCL, - cvsroot_files[i].cf_mode); - if (fd == -1) - fatal("cvs_init_create_file: open failed: %s", - strerror(errno)); - - (void)close(fd); - - strlcat(path, RCS_FILE_EXT, sizeof(path)); - rfp = rcs_open(path, RCS_WRITE|RCS_CREATE, 0640); - if (rfp == NULL) - return; - - rcs_close(rfp); + if ((fd = open(path, openflags, 0444)) == -1) + fatal("init_mkfile: open: `%s': %s", path, strerror(errno)); + + if (content != NULL) { + for (p = content; *p != NULL; ++p) { + len = strlen(*p); + b = cvs_buf_alloc(len, BUF_AUTOEXT); + + if (cvs_buf_append(b, *p, strlen(*p)) < 0) + fatal("init_mkfile: cvs_buf_append"); + + if (cvs_buf_write_fd(b, fd) < 0) + fatal("init_mkfile: cvs_buf_write_fd"); + + cvs_buf_free(b); } } + + /* + * Make sure history and val-tags files are world-writable. + * Every user should be able to write to them. + */ + if (strcmp(strrchr(CVS_PATH_HISTORY, '/'), strrchr(path, '/')) == 0 || + strcmp(strrchr(CVS_PATH_VALTAGS, '/'), strrchr(path, '/')) == 0) { + (void)fchmod(fd, 0666); + goto out; + } + + rpath = xstrdup(path); + if (strlcat(rpath, RCS_FILE_EXT, MAXPATHLEN) >= MAXPATHLEN) + fatal("init_mkfile: truncation"); + + if ((file = rcs_open(rpath, fd, rcsflags, 0444)) == NULL) + fatal("failed to create RCS file for `%s'", path); + + if ((b = cvs_buf_load(path, BUF_AUTOEXT)) == NULL) + fatal("init_mkfile: failed to load %s", path); + + cvs_buf_putc(b, '\0'); + d = cvs_buf_release(b); + + if (rcs_rev_add(file, RCS_HEAD_REV, "initial checkin", -1, NULL) == -1) + fatal("init_mkfile: failed to add new revision"); + + if (rcs_deltatext_set(file, file->rf_head, d) == -1) + fatal("init_mkfile: failed to set delta"); + + file->rf_flags &= ~RCS_SYNCED; + rcs_close(file); + xfree(rpath); +out: + (void)close(fd); + + if (d != NULL) + xfree(d); } diff --git a/usr.bin/cvs/init.h b/usr.bin/cvs/init.h new file mode 100644 index 00000000000..ebcb252c753 --- /dev/null +++ b/usr.bin/cvs/init.h @@ -0,0 +1,31 @@ +/* $OpenBSD: init.h,v 1.1 2006/06/12 13:56:00 xsa Exp $ */ +/* + * Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef INIT_H +#define INIT_H + +static const char *const config_contents[] = { + "# Set name of the local tag to use in addition to `Id'\n", + "#tag=OpenBSD\n", + "# Set default file creation mode mask\n", + "#umask=002\n", + "# Set default data resource limit to use\n", + "#dlimit=49152\n", + NULL +}; + +#endif /* INIT_H */ |