]>
git.saurik.com Git - apple/libc.git/blob - gen/getttyent.c
2 * Copyright (c) 1999, 2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 * Copyright (c) 1989, 1993
25 * The Regents of the University of California. All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgement:
37 * This product includes software developed by the University of
38 * California, Berkeley and its contributors.
39 * 4. Neither the name of the University nor the names of its contributors
40 * may be used to endorse or promote products derived from this software
41 * without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 #include "xlocale_private.h"
66 #pragma clang diagnostic push
67 #pragma clang diagnostic ignored "-Wstrict-prototypes"
76 register struct ttyent
*t
;
79 while ((t
= getttyent()) != NULL
)
80 if (!strcmp(tty
, t
->ty_name
))
86 static char *skip(), *value();
89 * 4372480: Support for sequences in the tty name. Expressions like [000-999]
90 * for decimal sequences and [0x0-0xf] for hexidecimal sequences causes a
91 * sequence of all combinations of names to be returned by getttyent().
93 * There is also a slot=nn option, which will cause getttyent() to return
94 * non-existent ttyent structs until the slot number nn is reached. Note, slot
101 char fmt
[NAME_MAX
+ 17];
104 static const char *brapat
= "\\[(.*)]";
105 static regex_t brapreg
;
106 static const char *decpat
= "^([0-9]+)-([0-9]+)$";
107 static regex_t decpreg
;
108 static const char *hexpat
= "^0x([0-9a-f]+)-0x([0-9a-f]+)$";
109 static regex_t hexpreg
;
110 static struct seq
*seq
= NULL
;
116 static struct ttyent tty
;
117 static const struct ttyent nonexistent
= {
118 "\01", /* this shouldn't match anything */
128 #define MAXLINELENGTH 1024
129 static char *line
= NULL
;
130 locale_t loc
= __current_locale();
133 regmatch_t match
[3], save
, bracket
;
135 if ( line
== NULL
) {
136 line
= malloc(MAXLINELENGTH
);
141 if (!tf
&& !setttyent())
145 if (slot
< seq
->first
) {
147 * the slot= option was set, and we are returning non-existent
148 * entries until we catch up.
151 return (struct ttyent
*)&nonexistent
;
154 if (seq
->count
> 0) {
156 * generate the next tty name; the rest of the tty entries
159 sprintf(tty
.ty_name
, seq
->fmt
, seq
->index
++);
165 if (slot
== seq
->first
) {
167 * this was a regular entry with slot=
174 if (!fgets(p
= line
, MAXLINELENGTH
, tf
))
176 /* skip lines that are too big */
177 if (!index(p
, '\n')) {
178 while ((c
= getc(tf
)) != '\n' && c
!= EOF
)
182 while (isspace_l(*p
, loc
))
191 if (!*(tty
.ty_getty
= p
))
192 tty
.ty_getty
= tty
.ty_type
= NULL
;
195 if (!*(tty
.ty_type
= p
))
201 tty
.ty_window
= NULL
;
202 tty
.ty_onerror
= NULL
;
203 tty
.ty_onoption
= NULL
;
205 #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace_l(p[sizeof(e) - 1], loc)
206 #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
208 for (; *p
; p
= skip(p
)) {
210 tty
.ty_status
&= ~TTY_ON
;
211 else if (scmp(_TTYS_ON
))
212 tty
.ty_status
|= TTY_ON
;
213 else if (scmp(_TTYS_SECURE
))
214 tty
.ty_status
|= TTY_SECURE
;
215 else if (vcmp(_TTYS_WINDOW
))
216 tty
.ty_window
= value(p
);
217 else if (vcmp(_TTYS_ONERROR
))
218 tty
.ty_onerror
= value(p
);
219 else if (vcmp(_TTYS_ONOPTION
))
220 tty
.ty_onoption
= value(p
);
221 else if (vcmp(_TTYS_SLOT
)) {
222 char *slotstr
= value(p
);
224 newslot
= atoi(slotstr
);
229 if (zapchar
== '#' || *p
== '#')
230 while ((c
= *++p
) == ' ' || c
== '\t')
235 if ((p
= index(p
, '\n')) != NULL
)
238 /* check if tty.tyname has a sequence */
239 if (regexec(&brapreg
, tty
.ty_name
, 3, match
, 0) != 0)
243 * save the range of the bracketed range, so we can find the strings
247 /* use REG_STARTEND to limit matching with the bracketed range */
248 match
[0] = save
= match
[1];
249 if (regexec(&decpreg
, tty
.ty_name
, 3, match
, REG_STARTEND
) == 0) {
250 /* a decimal range */
251 b
= strtol(tty
.ty_name
+ match
[1].rm_so
, NULL
, 10);
252 e
= strtol(tty
.ty_name
+ match
[2].rm_so
, NULL
, 10);
256 if (regexec(&hexpreg
, tty
.ty_name
, 3, match
, REG_STARTEND
) == 0) {
257 /* a hexidecimal range */
258 b
= strtol(tty
.ty_name
+ match
[1].rm_so
, NULL
, 16);
259 e
= strtol(tty
.ty_name
+ match
[2].rm_so
, NULL
, 16);
264 if (b
> e
) /* skip */
267 /* seq->first is already less than slot, so just leave it */
268 seq
->count
= (int)(e
- b
+ 1);
269 seq
->index
= (int)(b
);
271 * The fmt string contains the characters before the bracket, the
272 * a format specifier (either decimal or hex) and any characters
273 * after the bracket. Note that the length of the lower range is
274 * use as a minimum digit length, with zero fill, so the format
275 * specifier will look something like %03d.
277 sprintf(seq
->fmt
, "%.*s%%0%d%c%s",
278 (int)bracket
.rm_so
, tty
.ty_name
,
279 (int)(match
[1].rm_eo
- match
[1].rm_so
),
281 tty
.ty_name
+ bracket
.rm_eo
);
284 if (newslot
> slot
) {
285 /* set up to skip until newslot */
286 seq
->first
= newslot
;
289 if (seq
->count
> 0) /* restart if we are doing a sequence */
291 /* regular single value return */
299 * Skip over the current field, removing quotes, and return a pointer to
309 for (q
= 0, t
= p
; (c
= *p
) != '\0'; p
++) {
311 q
^= QUOTED
; /* obscure, but nice */
314 if (q
== QUOTED
&& *p
== '\\' && *(p
+1) == '"')
324 if (c
== '\t' || c
== ' ' || c
== '\n') {
327 while ((c
= *p
) == '\t' || c
== ' ' || c
== '\n')
341 return ((p
= index(p
, '=')) ? ++p
: NULL
);
348 /* initialize seq and the three regexp patterns */
350 if (regcomp(&brapreg
, brapat
, REG_EXTENDED
) != 0)
352 if (regcomp(&decpreg
, decpat
, REG_EXTENDED
) != 0) {
356 if (regcomp(&hexpreg
, hexpat
, REG_EXTENDED
| REG_ICASE
) != 0) {
361 if ((seq
= malloc(sizeof(struct seq
))) == NULL
) {
368 seq
->first
= seq
->count
= 0;
374 } else if ((tf
= fopen(_PATH_TTYS
, "r")) != NULL
)
385 rval
= !(fclose(tf
) == EOF
);
391 #pragma clang diagnostic pop