* Nuke ~771 __P()'s from our tree.
[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.4 2003/11/01 17:16:02 drhodus 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(char *, char *, char**, struct list *);
76 void listall(char *, struct list *);
77 void parse(char *, char *, int);
78 static void usage(void);
79
80 int
81 main(int argc, char **argv)
82 {
83         char *path;
84         int ch;
85
86         while ((ch = getopt(argc, argv, "Aan")) != -1) {
87                 switch (ch) {
88
89                 case 'A':
90                         Aflag = 1;
91                         break;
92
93                 case 'a':
94                         aflag = 1;
95                         break;
96
97                 case 'n':
98                         nflag = 1;
99                         break;
100
101                 default:
102                         usage();
103                 }
104         }
105         argc -= optind;
106         argv += optind;
107
108         if (argc == 0)
109                 usage();
110         path = *argv++;
111         if (strcmp(path, "-") == 0)
112                 stdinflag = 1;
113         argc--;
114         if (Aflag || aflag) {
115                 listall(path, &pclist);
116                 exit(0);
117         }
118         if (argc == 0)
119                 usage();
120         while (argc-- > 0)
121                 parse(path, *argv, 1);
122         exit(0);
123 }
124
125 /*
126  * List all variables known to the system.
127  */
128 void
129 listall(char *path, struct list *lp)
130 {
131         int lvl2;
132
133         if (lp->list == 0)
134                 return;
135         for (lvl2 = 0; lvl2 < lp->size; lvl2++) {
136                 if (lp->list[lvl2].ctl_name == 0)
137                         continue;
138                 parse(path, lp->list[lvl2].ctl_name, Aflag);
139         }
140 }
141
142 /*
143  * Parse a name into an index.
144  * Lookup and print out the attribute if it exists.
145  */
146 void
147 parse(char *pathname, char *string, int flags)
148 {
149         int indx, value;
150         char *bufp, buf[BUFSIZ];
151
152         bufp = buf;
153         snprintf(buf, BUFSIZ, "%s", string);
154         if ((indx = findname(string, "top", &bufp, &pclist)) == -1)
155                 return;
156         if (bufp) {
157                 warnx("name %s in %s is unknown", *bufp, string);
158                 return;
159         }
160         if (stdinflag)
161                 value = fpathconf(0, indx);
162         else
163                 value = pathconf(pathname, indx);
164         if (value == -1) {
165                 if (flags == 0)
166                         return;
167                 switch (errno) {
168                 case EOPNOTSUPP:
169                         warnx("%s: value is not available", string);
170                         return;
171                 case ENOTDIR:
172                         warnx("%s: specification is incomplete", string);
173                         return;
174                 case ENOMEM:
175                         warnx("%s: type is unknown to this program", string);
176                         return;
177                 default:
178                         warn("%s", string);
179                         return;
180                 }
181         }
182         if (!nflag)
183                 fprintf(stdout, "%s = ", string);
184         fprintf(stdout, "%d\n", value);
185 }
186
187 /*
188  * Scan a list of names searching for a particular name.
189  */
190 int
191 findname(char *string, char *level, char **bufp, struct list *namelist)
192         char *string;
193         char *level;
194         char **bufp;
195         struct list *namelist;
196 {
197         char *name;
198         int i;
199
200         if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) {
201                 warnx("%s: incomplete specification", string);
202                 return (-1);
203         }
204         for (i = 0; i < namelist->size; i++)
205                 if (namelist->list[i].ctl_name != NULL &&
206                     strcmp(name, namelist->list[i].ctl_name) == 0)
207                         break;
208         if (i == namelist->size) {
209                 warnx("%s level name %s in %s is invalid", level, name, string);
210                 return (-1);
211         }
212         return (i);
213 }
214
215 static void
216 usage(void)
217 {
218
219         (void)fprintf(stderr, "%s\n%s\n%s\n",
220                 "usage: pathname [-n] variable ...",
221                 "       pathname [-n] -a",
222                 "       pathname [-n] -A");
223         exit(1);
224 }