Commit | Line | Data |
---|---|---|
29f2fd55 KB |
1 | /* |
2 | * Copyright (c) 1993 | |
3 | * The Regents of the University of California. All rights reserved. | |
4 | * | |
5 | * %sccs.include.redist.c% | |
6 | */ | |
7 | ||
8 | #ifndef lint | |
9 | static char copyright[] = | |
10 | "@(#) Copyright (c) 1993\n\ | |
11 | The Regents of the University of California. All rights reserved.\n"; | |
12 | #endif /* not lint */ | |
13 | ||
14 | #ifndef lint | |
452e8b8f | 15 | static char sccsid[] = "@(#)pathconf.c 8.1 (Berkeley) %G%"; |
29f2fd55 KB |
16 | #endif /* not lint */ |
17 | ||
18 | #include <sys/param.h> | |
19 | #include <sys/sysctl.h> | |
20 | #include <sys/unistd.h> | |
21 | ||
22 | #include <errno.h> | |
23 | #include <stdio.h> | |
24 | #include <stdlib.h> | |
25 | #include <string.h> | |
26 | ||
27 | #define PC_NAMES { \ | |
28 | { 0, 0 }, \ | |
29 | { "link_max", CTLTYPE_INT }, \ | |
30 | { "max_canon", CTLTYPE_INT }, \ | |
31 | { "max_input", CTLTYPE_INT }, \ | |
32 | { "name_max", CTLTYPE_INT }, \ | |
33 | { "path_max", CTLTYPE_INT }, \ | |
34 | { "pipe_buf", CTLTYPE_INT }, \ | |
35 | { "chown_restricted", CTLTYPE_INT }, \ | |
36 | { "no_trunc", CTLTYPE_INT }, \ | |
37 | { "vdisable", CTLTYPE_INT }, \ | |
38 | } | |
39 | #define PC_MAXID 10 | |
40 | ||
41 | struct ctlname pcnames[] = PC_NAMES; | |
42 | char names[BUFSIZ]; | |
43 | ||
44 | struct list { | |
45 | struct ctlname *list; | |
46 | int size; | |
47 | }; | |
48 | struct list pclist = { pcnames, PC_MAXID }; | |
49 | ||
50 | int Aflag, aflag, nflag, wflag, stdinflag; | |
51 | ||
52 | int | |
53 | main(argc, argv) | |
54 | int argc; | |
55 | char *argv[]; | |
56 | { | |
57 | extern char *optarg; | |
58 | extern int optind; | |
59 | char *path; | |
60 | int ch; | |
61 | ||
62 | while ((ch = getopt(argc, argv, "Aan")) != EOF) { | |
63 | switch (ch) { | |
64 | ||
65 | case 'A': | |
66 | Aflag = 1; | |
67 | break; | |
68 | ||
69 | case 'a': | |
70 | aflag = 1; | |
71 | break; | |
72 | ||
73 | case 'n': | |
74 | nflag = 1; | |
75 | break; | |
76 | ||
77 | default: | |
78 | usage(); | |
79 | } | |
80 | } | |
81 | argc -= optind; | |
82 | argv += optind; | |
83 | ||
84 | if (argc == 0) | |
85 | usage(); | |
86 | path = *argv++; | |
87 | if (strcmp(path, "-") == 0) | |
88 | stdinflag = 1; | |
89 | argc--; | |
90 | if (Aflag || aflag) { | |
91 | listall(path, &pclist); | |
92 | exit(0); | |
93 | } | |
94 | if (argc == 0) | |
95 | usage(); | |
96 | while (argc-- > 0) | |
97 | parse(path, *argv, 1); | |
98 | exit(0); | |
99 | } | |
100 | ||
101 | /* | |
102 | * List all variables known to the system. | |
103 | */ | |
104 | listall(path, lp) | |
105 | char *path; | |
106 | struct list *lp; | |
107 | { | |
108 | int lvl2; | |
109 | ||
110 | if (lp->list == 0) | |
111 | return; | |
112 | for (lvl2 = 0; lvl2 < lp->size; lvl2++) { | |
113 | if (lp->list[lvl2].ctl_name == 0) | |
114 | continue; | |
115 | parse(path, lp->list[lvl2].ctl_name, Aflag); | |
116 | } | |
117 | } | |
118 | ||
119 | /* | |
120 | * Parse a name into an index. | |
121 | * Lookup and print out the attribute if it exists. | |
122 | */ | |
123 | parse(pathname, string, flags) | |
124 | char *pathname; | |
125 | char *string; | |
126 | int flags; | |
127 | { | |
128 | int indx, value; | |
129 | char *bufp, buf[BUFSIZ]; | |
130 | ||
131 | bufp = buf; | |
132 | snprintf(buf, BUFSIZ, "%s", string); | |
133 | if ((indx = findname(string, "top", &bufp, &pclist)) == -1) | |
134 | return; | |
135 | if (bufp) { | |
136 | fprintf(stderr, "name %s in %s is unknown\n", *bufp, string); | |
137 | return; | |
138 | } | |
139 | if (stdinflag) | |
140 | value = fpathconf(0, indx); | |
141 | else | |
142 | value = pathconf(pathname, indx); | |
143 | if (value == -1) { | |
144 | if (flags == 0) | |
145 | return; | |
146 | switch (errno) { | |
147 | case EOPNOTSUPP: | |
148 | fprintf(stderr, "%s: value is not available\n", string); | |
149 | return; | |
150 | case ENOTDIR: | |
151 | fprintf(stderr, "%s: specification is incomplete\n", | |
152 | string); | |
153 | return; | |
154 | case ENOMEM: | |
155 | fprintf(stderr, "%s: type is unknown to this program\n", | |
156 | string); | |
157 | return; | |
158 | default: | |
159 | perror(string); | |
160 | return; | |
161 | } | |
162 | } | |
163 | if (!nflag) | |
164 | fprintf(stdout, "%s = ", string); | |
165 | fprintf(stdout, "%d\n", value); | |
166 | } | |
167 | ||
168 | /* | |
169 | * Scan a list of names searching for a particular name. | |
170 | */ | |
171 | findname(string, level, bufp, namelist) | |
172 | char *string; | |
173 | char *level; | |
174 | char **bufp; | |
175 | struct list *namelist; | |
176 | { | |
177 | char *name; | |
178 | int i; | |
179 | ||
180 | if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) { | |
181 | fprintf(stderr, "%s: incomplete specification\n", string); | |
182 | return (-1); | |
183 | } | |
184 | for (i = 0; i < namelist->size; i++) | |
185 | if (namelist->list[i].ctl_name != NULL && | |
186 | strcmp(name, namelist->list[i].ctl_name) == 0) | |
187 | break; | |
188 | if (i == namelist->size) { | |
189 | fprintf(stderr, "%s level name %s in %s is invalid\n", | |
190 | level, name, string); | |
191 | return (-1); | |
192 | } | |
193 | return (i); | |
194 | } | |
195 | ||
196 | usage() | |
197 | { | |
198 | ||
199 | (void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n", | |
200 | "pathname [-n] variable ...", | |
201 | "pathname [-n] -a", "pathname [-n] -A"); | |
202 | exit(1); | |
203 | } |