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