xref: /original-bsd/usr.sbin/sysctl/pathconf.c (revision c3e32dec)
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
15 static char sccsid[] = "@(#)pathconf.c	8.1 (Berkeley) 06/06/93";
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 }
204