1 /* $OpenBSD: add.c,v 1.11 2004/12/21 17:50:40 jfb Exp $ */ 2 /* 3 * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. The name of the author may not be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 18 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <sys/types.h> 28 29 #include <errno.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <sysexits.h> 34 #include <unistd.h> 35 36 #include "cvs.h" 37 #include "log.h" 38 #include "proto.h" 39 40 41 extern char *__progname; 42 43 44 int cvs_add_file (CVSFILE *, void *); 45 46 47 /* 48 * cvs_add() 49 * 50 * Handler for the `cvs add' command. 51 * Returns 0 on success, or one of the known system exit codes on failure. 52 */ 53 int 54 cvs_add(int argc, char **argv) 55 { 56 int i, ch; 57 char *kflag, *msg; 58 struct cvsroot *root; 59 60 kflag = msg = NULL; 61 62 while ((ch = getopt(argc, argv, "k:m:")) != -1) { 63 switch (ch) { 64 case 'k': 65 kflag = optarg; 66 break; 67 case 'm': 68 msg = optarg; 69 break; 70 default: 71 return (EX_USAGE); 72 } 73 } 74 75 argc -= optind; 76 argv += optind; 77 78 if (argc == 0) 79 return (EX_USAGE); 80 81 cvs_files = cvs_file_getspec(argv, argc, 0); 82 if (cvs_files == NULL) 83 return (EX_DATAERR); 84 85 root = CVS_DIR_ROOT(cvs_files); 86 if (root == NULL) { 87 cvs_log(LP_ERR, 88 "No CVSROOT specified! Please use the `-d' option"); 89 cvs_log(LP_ERR, 90 "or set the CVSROOT environment variable."); 91 return (EX_USAGE); 92 } 93 if ((root->cr_method != CVS_METHOD_LOCAL) && (cvs_connect(root) < 0)) 94 return (EX_PROTOCOL); 95 96 cvs_file_examine(cvs_files, cvs_add_file, NULL); 97 98 if (root->cr_method != CVS_METHOD_LOCAL) { 99 if (cvs_senddir(root, cvs_files) < 0) 100 return (EX_PROTOCOL); 101 102 for (i = 0; i < argc; i++) 103 if (cvs_sendarg(root, argv[i], 0) < 0) 104 return (EX_PROTOCOL); 105 106 if (cvs_sendreq(root, CVS_REQ_ADD, NULL) < 0) 107 return (EX_PROTOCOL); 108 } 109 110 return (0); 111 } 112 113 114 int 115 cvs_add_file(CVSFILE *cf, void *arg) 116 { 117 int ret; 118 struct cvsroot *root; 119 120 ret = 0; 121 root = CVS_DIR_ROOT(cf); 122 123 if (cf->cf_type == DT_DIR) { 124 if (root->cr_method != CVS_METHOD_LOCAL) { 125 if (cf->cf_cvstat == CVS_FST_UNKNOWN) 126 ret = cvs_sendreq(root, CVS_REQ_QUESTIONABLE, 127 CVS_FILE_NAME(cf)); 128 else 129 ret = cvs_senddir(root, cf); 130 } 131 132 return (ret); 133 } 134 135 if (root->cr_method != CVS_METHOD_LOCAL) { 136 ret = cvs_sendreq(root, CVS_REQ_ADD, CVS_FILE_NAME(cf)); 137 } else { 138 cvs_log(LP_INFO, "scheduling file `%s' for addition", 139 CVS_FILE_NAME(cf)); 140 cvs_log(LP_INFO, "use `%s commit' to add this file permanently", 141 __progname); 142 } 143 144 return (ret); 145 } 146