1 /* $OpenBSD: distopt.c,v 1.11 2009/10/27 23:59:42 deraadt 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 34 /* 35 * Dist Option functions 36 */ 37 38 39 /* 40 * Distfile Option Information 41 */ 42 DISTOPTINFO distoptinfo[] = { 43 { DO_CHKNFS, "chknfs", NULL, 0}, 44 { DO_CHKREADONLY, "chkreadonly", NULL, 0}, 45 { DO_CHKSYM, "chksym", NULL, 0}, 46 { DO_COMPARE, "compare", NULL, 0}, 47 { DO_DEFGROUP, "defgroup", defgroup, sizeof(defgroup) }, 48 { DO_DEFOWNER, "defowner", defowner, sizeof(defowner) }, 49 { DO_FOLLOW, "follow", NULL, 0}, 50 { DO_HISTORY, "history", NULL, 0}, 51 { DO_IGNLNKS, "ignlnks", NULL, 0}, 52 { DO_NOCHKGROUP, "nochkgroup", NULL, 0}, 53 { DO_NOCHKMODE, "nochkmode", NULL, 0}, 54 { DO_NOCHKOWNER, "nochkowner", NULL, 0}, 55 { DO_NODESCEND, "nodescend", NULL, 0}, 56 { DO_NOEXEC, "noexec", NULL, 0}, 57 { DO_NUMCHKGROUP, "numchkgroup", NULL, 0}, 58 { DO_NUMCHKOWNER, "numchkowner", NULL, 0}, 59 { DO_QUIET, "quiet", NULL, 0}, 60 { DO_REMOVE, "remove", NULL, 0}, 61 { DO_SAVETARGETS, "savetargets", NULL, 0}, 62 { DO_SPARSE, "sparse", NULL, 0}, 63 { DO_UPDATEPERM, "updateperm", NULL, 0}, 64 { DO_VERIFY, "verify", NULL, 0}, 65 { DO_WHOLE, "whole", NULL, 0}, 66 { DO_YOUNGER, "younger", NULL, 0}, 67 { 0 }, 68 }; 69 70 /* 71 * Get a Distfile Option entry named "name". 72 */ 73 DISTOPTINFO * 74 getdistopt(char *name, int *len) 75 { 76 int i; 77 78 for (i = 0; distoptinfo[i].do_name; ++i) 79 if (strncasecmp(name, distoptinfo[i].do_name, 80 *len = strlen(distoptinfo[i].do_name)) == 0) 81 return(&distoptinfo[i]); 82 83 return(NULL); 84 } 85 86 /* 87 * Parse a dist option string. Set option flags to optptr. 88 * If doerrs is true, print out own error message. Returns 89 * 0 on success. 90 */ 91 int 92 parsedistopts(char *str, opt_t *optptr, int doerrs) 93 { 94 char *string, *optstr; 95 DISTOPTINFO *distopt; 96 int len; 97 98 /* strtok() is destructive */ 99 string = xstrdup(str); 100 101 for (optstr = strtok(string, ","); optstr; 102 optstr = strtok(NULL, ",")) { 103 /* Try Yes */ 104 if ((distopt = getdistopt(optstr, &len)) != NULL) { 105 FLAG_ON(*optptr, distopt->do_value); 106 if (distopt->do_arg && optstr[len] == '=') 107 (void) strlcpy(distopt->do_arg, 108 &optstr[len + 1], distopt->arg_size); 109 continue; 110 } 111 112 /* Try No */ 113 if ((distopt = getdistopt(optstr+2, &len)) != NULL) { 114 FLAG_OFF(*optptr, distopt->do_value); 115 continue; 116 } 117 118 if (doerrs) 119 error("Dist option \"%s\" is not valid.", optstr); 120 } 121 122 if (string) 123 (void) free(string); 124 125 return(nerrs); 126 } 127 128 /* 129 * Get a list of the Distfile Option Entries. 130 */ 131 char * 132 getdistoptlist(void) 133 { 134 int i; 135 static char buf[1024]; 136 137 for (i = 0, buf[0] = CNULL; distoptinfo[i].do_name; ++i) { 138 if (buf[0] == CNULL) 139 (void) strlcpy(buf, distoptinfo[i].do_name, sizeof buf); 140 else { 141 (void) strlcat(buf, ",", sizeof buf); 142 (void) strlcat(buf, distoptinfo[i].do_name, sizeof buf); 143 } 144 } 145 146 return(buf); 147 } 148 149 /* 150 * Get a list of the Distfile Option Entries for each enabled 151 * value in "opts". 152 */ 153 char * 154 getondistoptlist(opt_t opts) 155 { 156 int i; 157 static char buf[1024]; 158 159 for (i = 0, buf[0] = CNULL; distoptinfo[i].do_name; ++i) { 160 if (!IS_ON(opts, distoptinfo[i].do_value)) 161 continue; 162 163 if (buf[0] == CNULL) 164 (void) strlcpy(buf, distoptinfo[i].do_name, sizeof buf); 165 else { 166 (void) strlcat(buf, ",", sizeof buf); 167 (void) strlcat(buf, distoptinfo[i].do_name, sizeof buf); 168 } 169 if (distoptinfo[i].do_arg) { 170 (void) strlcat(buf, "=", sizeof buf); 171 (void) strlcat(buf, distoptinfo[i].do_arg, sizeof buf); 172 } 173 } 174 175 return(buf); 176 } 177 178