1 1.7 atatat /* $NetBSD: pathconf.c,v 1.7 2004/03/25 19:36:27 atatat Exp $ */ 2 1.2 thorpej 3 1.1 cgd /* 4 1.1 cgd * Copyright (c) 1993 5 1.1 cgd * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.6 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 cgd * may be used to endorse or promote products derived from this software 17 1.1 cgd * without specific prior written permission. 18 1.1 cgd * 19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 cgd * SUCH DAMAGE. 30 1.1 cgd */ 31 1.1 cgd 32 1.1 cgd #ifndef lint 33 1.1 cgd static char copyright[] = 34 1.1 cgd "@(#) Copyright (c) 1993\n\ 35 1.1 cgd The Regents of the University of California. All rights reserved.\n"; 36 1.1 cgd #endif /* not lint */ 37 1.1 cgd 38 1.1 cgd #ifndef lint 39 1.2 thorpej #if 0 40 1.1 cgd static char sccsid[] = "@(#)pathconf.c 8.1 (Berkeley) 6/6/93"; 41 1.2 thorpej #else 42 1.7 atatat static char rcsid[] = "$NetBSD: pathconf.c,v 1.7 2004/03/25 19:36:27 atatat Exp $"; 43 1.2 thorpej #endif 44 1.1 cgd #endif /* not lint */ 45 1.1 cgd 46 1.1 cgd #include <sys/param.h> 47 1.1 cgd #include <sys/sysctl.h> 48 1.1 cgd #include <sys/unistd.h> 49 1.1 cgd 50 1.1 cgd #include <errno.h> 51 1.1 cgd #include <stdio.h> 52 1.1 cgd #include <stdlib.h> 53 1.1 cgd #include <string.h> 54 1.1 cgd 55 1.1 cgd #define PC_NAMES { \ 56 1.1 cgd { 0, 0 }, \ 57 1.1 cgd { "link_max", CTLTYPE_INT }, \ 58 1.1 cgd { "max_canon", CTLTYPE_INT }, \ 59 1.1 cgd { "max_input", CTLTYPE_INT }, \ 60 1.1 cgd { "name_max", CTLTYPE_INT }, \ 61 1.1 cgd { "path_max", CTLTYPE_INT }, \ 62 1.1 cgd { "pipe_buf", CTLTYPE_INT }, \ 63 1.1 cgd { "chown_restricted", CTLTYPE_INT }, \ 64 1.1 cgd { "no_trunc", CTLTYPE_INT }, \ 65 1.1 cgd { "vdisable", CTLTYPE_INT }, \ 66 1.1 cgd } 67 1.1 cgd #define PC_MAXID 10 68 1.1 cgd 69 1.1 cgd struct ctlname pcnames[] = PC_NAMES; 70 1.1 cgd char names[BUFSIZ]; 71 1.1 cgd 72 1.1 cgd struct list { 73 1.1 cgd struct ctlname *list; 74 1.1 cgd int size; 75 1.1 cgd }; 76 1.1 cgd struct list pclist = { pcnames, PC_MAXID }; 77 1.1 cgd 78 1.1 cgd int Aflag, aflag, nflag, wflag, stdinflag; 79 1.1 cgd 80 1.1 cgd int 81 1.1 cgd main(argc, argv) 82 1.1 cgd int argc; 83 1.1 cgd char *argv[]; 84 1.1 cgd { 85 1.1 cgd char *path; 86 1.1 cgd int ch; 87 1.1 cgd 88 1.3 lukem while ((ch = getopt(argc, argv, "Aan")) != -1) { 89 1.1 cgd switch (ch) { 90 1.1 cgd 91 1.1 cgd case 'A': 92 1.1 cgd Aflag = 1; 93 1.1 cgd break; 94 1.1 cgd 95 1.1 cgd case 'a': 96 1.1 cgd aflag = 1; 97 1.1 cgd break; 98 1.1 cgd 99 1.1 cgd case 'n': 100 1.1 cgd nflag = 1; 101 1.1 cgd break; 102 1.1 cgd 103 1.1 cgd default: 104 1.1 cgd usage(); 105 1.1 cgd } 106 1.1 cgd } 107 1.1 cgd argc -= optind; 108 1.1 cgd argv += optind; 109 1.1 cgd 110 1.1 cgd if (argc == 0) 111 1.1 cgd usage(); 112 1.1 cgd path = *argv++; 113 1.1 cgd if (strcmp(path, "-") == 0) 114 1.1 cgd stdinflag = 1; 115 1.1 cgd argc--; 116 1.1 cgd if (Aflag || aflag) { 117 1.1 cgd listall(path, &pclist); 118 1.1 cgd exit(0); 119 1.1 cgd } 120 1.1 cgd if (argc == 0) 121 1.1 cgd usage(); 122 1.1 cgd while (argc-- > 0) 123 1.1 cgd parse(path, *argv, 1); 124 1.1 cgd exit(0); 125 1.1 cgd } 126 1.1 cgd 127 1.1 cgd /* 128 1.1 cgd * List all variables known to the system. 129 1.1 cgd */ 130 1.1 cgd listall(path, lp) 131 1.1 cgd char *path; 132 1.1 cgd struct list *lp; 133 1.1 cgd { 134 1.1 cgd int lvl2; 135 1.1 cgd 136 1.1 cgd if (lp->list == 0) 137 1.1 cgd return; 138 1.1 cgd for (lvl2 = 0; lvl2 < lp->size; lvl2++) { 139 1.1 cgd if (lp->list[lvl2].ctl_name == 0) 140 1.1 cgd continue; 141 1.1 cgd parse(path, lp->list[lvl2].ctl_name, Aflag); 142 1.1 cgd } 143 1.1 cgd } 144 1.1 cgd 145 1.1 cgd /* 146 1.1 cgd * Parse a name into an index. 147 1.1 cgd * Lookup and print out the attribute if it exists. 148 1.1 cgd */ 149 1.1 cgd parse(pathname, string, flags) 150 1.1 cgd char *pathname; 151 1.1 cgd char *string; 152 1.1 cgd int flags; 153 1.1 cgd { 154 1.1 cgd int indx, value; 155 1.1 cgd char *bufp, buf[BUFSIZ]; 156 1.1 cgd 157 1.1 cgd bufp = buf; 158 1.1 cgd snprintf(buf, BUFSIZ, "%s", string); 159 1.1 cgd if ((indx = findname(string, "top", &bufp, &pclist)) == -1) 160 1.1 cgd return; 161 1.1 cgd if (bufp) { 162 1.1 cgd fprintf(stderr, "name %s in %s is unknown\n", *bufp, string); 163 1.1 cgd return; 164 1.1 cgd } 165 1.1 cgd if (stdinflag) 166 1.1 cgd value = fpathconf(0, indx); 167 1.1 cgd else 168 1.1 cgd value = pathconf(pathname, indx); 169 1.1 cgd if (value == -1) { 170 1.1 cgd if (flags == 0) 171 1.1 cgd return; 172 1.1 cgd switch (errno) { 173 1.1 cgd case EOPNOTSUPP: 174 1.1 cgd fprintf(stderr, "%s: value is not available\n", string); 175 1.1 cgd return; 176 1.1 cgd case ENOTDIR: 177 1.1 cgd fprintf(stderr, "%s: specification is incomplete\n", 178 1.1 cgd string); 179 1.1 cgd return; 180 1.1 cgd case ENOMEM: 181 1.1 cgd fprintf(stderr, "%s: type is unknown to this program\n", 182 1.1 cgd string); 183 1.1 cgd return; 184 1.1 cgd default: 185 1.1 cgd perror(string); 186 1.1 cgd return; 187 1.1 cgd } 188 1.1 cgd } 189 1.1 cgd if (!nflag) 190 1.1 cgd fprintf(stdout, "%s = ", string); 191 1.1 cgd fprintf(stdout, "%d\n", value); 192 1.1 cgd } 193 1.1 cgd 194 1.1 cgd /* 195 1.1 cgd * Scan a list of names searching for a particular name. 196 1.1 cgd */ 197 1.1 cgd findname(string, level, bufp, namelist) 198 1.1 cgd char *string; 199 1.7 atatat const char *level; 200 1.1 cgd char **bufp; 201 1.1 cgd struct list *namelist; 202 1.1 cgd { 203 1.1 cgd char *name; 204 1.1 cgd int i; 205 1.1 cgd 206 1.1 cgd if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) { 207 1.1 cgd fprintf(stderr, "%s: incomplete specification\n", string); 208 1.1 cgd return (-1); 209 1.1 cgd } 210 1.1 cgd for (i = 0; i < namelist->size; i++) 211 1.1 cgd if (namelist->list[i].ctl_name != NULL && 212 1.1 cgd strcmp(name, namelist->list[i].ctl_name) == 0) 213 1.1 cgd break; 214 1.1 cgd if (i == namelist->size) { 215 1.1 cgd fprintf(stderr, "%s level name %s in %s is invalid\n", 216 1.1 cgd level, name, string); 217 1.1 cgd return (-1); 218 1.1 cgd } 219 1.1 cgd return (i); 220 1.1 cgd } 221 1.1 cgd 222 1.1 cgd usage() 223 1.1 cgd { 224 1.1 cgd 225 1.1 cgd (void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n", 226 1.1 cgd "pathname [-n] variable ...", 227 1.1 cgd "pathname [-n] -a", "pathname [-n] -A"); 228 1.1 cgd exit(1); 229 1.1 cgd } 230