1 /* $OpenBSD: distopt.c,v 1.9 2003/06/03 02:56:14 millert Exp $ */ 2 3 /* 4 * Copyright (c) 1983 Regents of the University of California. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include "defs.h" 33 #ifndef lint 34 #if 0 35 static char RCSid[] __attribute__((__unused__)) = 36 "$From: distopt.c,v 1.5 1999/08/04 15:57:33 christos Exp $"; 37 #else 38 static char RCSid[] __attribute__((__unused__)) = 39 "$OpenBSD: distopt.c,v 1.9 2003/06/03 02:56:14 millert Exp $"; 40 #endif 41 42 static char sccsid[] __attribute__((__unused__)) = 43 "@(#)distopt.c"; 44 45 static char copyright[] __attribute__((__unused__)) = 46 "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 47 All rights reserved.\n"; 48 #endif /* !lint */ 49 50 /* 51 * Dist Option functions 52 */ 53 54 55 /* 56 * Distfile Option Information 57 */ 58 DISTOPTINFO distoptinfo[] = { 59 { DO_CHKNFS, "chknfs", NULL, 0}, 60 { DO_CHKREADONLY, "chkreadonly", NULL, 0}, 61 { DO_CHKSYM, "chksym", NULL, 0}, 62 { DO_DEFGROUP, "defgroup", defgroup, sizeof(defgroup) }, 63 { DO_DEFOWNER, "defowner", defowner, sizeof(defowner) }, 64 { DO_COMPARE, "compare", NULL, 0}, 65 { DO_FOLLOW, "follow", NULL, 0}, 66 { DO_HISTORY, "history", NULL, 0}, 67 { DO_IGNLNKS, "ignlnks", NULL, 0}, 68 { DO_NOCHKGROUP, "nochkgroup", NULL, 0}, 69 { DO_NOCHKMODE, "nochkmode", NULL, 0}, 70 { DO_NOCHKOWNER, "nochkowner", NULL, 0}, 71 { DO_NODESCEND, "nodescend", NULL, 0}, 72 { DO_NOEXEC, "noexec", NULL, 0}, 73 { DO_NUMCHKGROUP, "numchkgroup", NULL, 0}, 74 { DO_NUMCHKOWNER, "numchkowner", NULL, 0}, 75 { DO_QUIET, "quiet", NULL, 0}, 76 { DO_REMOVE, "remove", NULL, 0}, 77 { DO_SAVETARGETS, "savetargets", NULL, 0}, 78 { DO_SPARSE, "sparse", NULL, 0}, 79 { DO_UPDATEPERM, "updateperm", NULL, 0}, 80 { DO_VERIFY, "verify", NULL, 0}, 81 { DO_WHOLE, "whole", NULL, 0}, 82 { DO_YOUNGER, "younger", NULL, 0}, 83 { 0 }, 84 }; 85 86 /* 87 * Get a Distfile Option entry named "name". 88 */ 89 DISTOPTINFO * 90 getdistopt(char *name, int *len) 91 { 92 int i; 93 94 for (i = 0; distoptinfo[i].do_name; ++i) 95 if (strncasecmp(name, distoptinfo[i].do_name, 96 *len = strlen(distoptinfo[i].do_name)) == 0) 97 return(&distoptinfo[i]); 98 99 return(NULL); 100 } 101 102 /* 103 * Parse a dist option string. Set option flags to optptr. 104 * If doerrs is true, print out own error message. Returns 105 * 0 on success. 106 */ 107 int 108 parsedistopts(char *str, opt_t *optptr, int doerrs) 109 { 110 char *string, *optstr; 111 DISTOPTINFO *distopt; 112 int len; 113 114 /* strtok() is destructive */ 115 string = xstrdup(str); 116 117 for (optstr = strtok(string, ","); optstr; 118 optstr = strtok(NULL, ",")) { 119 /* Try Yes */ 120 if ((distopt = getdistopt(optstr, &len)) != NULL) { 121 FLAG_ON(*optptr, distopt->do_value); 122 if (distopt->do_arg && optstr[len] == '=') 123 (void) strlcpy(distopt->do_arg, 124 &optstr[len + 1], distopt->arg_size); 125 continue; 126 } 127 128 /* Try No */ 129 if ((distopt = getdistopt(optstr+2, &len)) != NULL) { 130 FLAG_OFF(*optptr, distopt->do_value); 131 continue; 132 } 133 134 if (doerrs) 135 error("Dist option \"%s\" is not valid.", optstr); 136 } 137 138 if (string) 139 (void) free(string); 140 141 return(nerrs); 142 } 143 144 /* 145 * Get a list of the Distfile Option Entries. 146 */ 147 char * 148 getdistoptlist(void) 149 { 150 int i; 151 static char buf[1024]; 152 153 for (i = 0, buf[0] = CNULL; distoptinfo[i].do_name; ++i) { 154 if (buf[0] == CNULL) 155 (void) strlcpy(buf, distoptinfo[i].do_name, sizeof buf); 156 else { 157 (void) strlcat(buf, ",", sizeof buf); 158 (void) strlcat(buf, distoptinfo[i].do_name, sizeof buf); 159 } 160 } 161 162 return(buf); 163 } 164 165 /* 166 * Get a list of the Distfile Option Entries for each enabled 167 * value in "opts". 168 */ 169 char * 170 getondistoptlist(opt_t opts) 171 { 172 int i; 173 static char buf[1024]; 174 175 for (i = 0, buf[0] = CNULL; distoptinfo[i].do_name; ++i) { 176 if (!IS_ON(opts, distoptinfo[i].do_value)) 177 continue; 178 179 if (buf[0] == CNULL) 180 (void) strlcpy(buf, distoptinfo[i].do_name, sizeof buf); 181 else { 182 (void) strlcat(buf, ",", sizeof buf); 183 (void) strlcat(buf, distoptinfo[i].do_name, sizeof buf); 184 } 185 if (distoptinfo[i].do_arg) { 186 (void) strlcat(buf, "=", sizeof buf); 187 (void) strlcat(buf, distoptinfo[i].do_arg, sizeof buf); 188 } 189 } 190 191 return(buf); 192 } 193 194