]>
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"
73 register struct ttyent
*t
;
76 while ((t
= getttyent()) != NULL
)
77 if (!strcmp(tty
, t
->ty_name
))
83 static char *skip(), *value();
86 * 4372480: Support for sequences in the tty name. Expressions like [000-999]
87 * for decimal sequences and [0x0-0xf] for hexidecimal sequences causes a
88 * sequence of all combinations of names to be returned by getttyent().
90 * There is also a slot=nn option, which will cause getttyent() to return
91 * non-existent ttyent structs until the slot number nn is reached. Note, slot
98 char fmt
[NAME_MAX
+ 17];
101 static char brapat
[] = "\\[(.*)]";
102 static regex_t brapreg
;
103 static char decpat
[] = "^([0-9]+)-([0-9]+)$";
104 static regex_t decpreg
;
105 static char hexpat
[] = "^0x([0-9a-f]+)-0x([0-9a-f]+)$";
106 static regex_t hexpreg
;
107 static struct seq
*seq
= NULL
;
113 static struct ttyent tty
;
114 static struct ttyent nonexistent
= {
115 "\01", /* this shouldn't match anything */
125 #define MAXLINELENGTH 1024
126 static char *line
= NULL
;
127 locale_t loc
= __current_locale();
130 regmatch_t match
[3], save
, bracket
;
132 if ( line
== NULL
) {
133 line
= malloc(MAXLINELENGTH
);
138 if (!tf
&& !setttyent())
142 if (slot
< seq
->first
) {
144 * the slot= option was set, and we are returning non-existent
145 * entries until we catch up.
151 if (seq
->count
> 0) {
153 * generate the next tty name; the rest of the tty entries
156 sprintf(tty
.ty_name
, seq
->fmt
, seq
->index
++);
162 if (slot
== seq
->first
) {
164 * this was a regular entry with slot=
171 if (!fgets(p
= line
, MAXLINELENGTH
, tf
))
173 /* skip lines that are too big */
174 if (!index(p
, '\n')) {
175 while ((c
= getc(tf
)) != '\n' && c
!= EOF
)
179 while (isspace_l(*p
, loc
))
188 if (!*(tty
.ty_getty
= p
))
189 tty
.ty_getty
= tty
.ty_type
= NULL
;
192 if (!*(tty
.ty_type
= p
))
198 tty
.ty_window
= NULL
;
199 tty
.ty_onerror
= NULL
;
200 tty
.ty_onoption
= NULL
;
202 #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace_l(p[sizeof(e) - 1], loc)
203 #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
205 for (; *p
; p
= skip(p
)) {
207 tty
.ty_status
&= ~TTY_ON
;
208 else if (scmp(_TTYS_ON
))
209 tty
.ty_status
|= TTY_ON
;
210 else if (scmp(_TTYS_SECURE
))
211 tty
.ty_status
|= TTY_SECURE
;
212 else if (vcmp(_TTYS_WINDOW
))
213 tty
.ty_window
= value(p
);
214 else if (vcmp(_TTYS_ONERROR
))
215 tty
.ty_onerror
= value(p
);
216 else if (vcmp(_TTYS_ONOPTION
))
217 tty
.ty_onoption
= value(p
);
218 else if (vcmp(_TTYS_SLOT
)) {
219 char *slotstr
= value(p
);
221 newslot
= atoi(slotstr
);
226 if (zapchar
== '#' || *p
== '#')
227 while ((c
= *++p
) == ' ' || c
== '\t')
232 if ((p
= index(p
, '\n')) != NULL
)
235 /* check if tty.tyname has a sequence */
236 if (regexec(&brapreg
, tty
.ty_name
, 3, match
, 0) != 0)
240 * save the range of the bracketed range, so we can find the strings
244 /* use REG_STARTEND to limit matching with the bracketed range */
245 match
[0] = save
= match
[1];
246 if (regexec(&decpreg
, tty
.ty_name
, 3, match
, REG_STARTEND
) == 0) {
247 /* a decimal range */
248 b
= strtol(tty
.ty_name
+ match
[1].rm_so
, NULL
, 10);
249 e
= strtol(tty
.ty_name
+ match
[2].rm_so
, NULL
, 10);
253 if (regexec(&hexpreg
, tty
.ty_name
, 3, match
, REG_STARTEND
) == 0) {
254 /* a hexidecimal range */
255 b
= strtol(tty
.ty_name
+ match
[1].rm_so
, NULL
, 16);
256 e
= strtol(tty
.ty_name
+ match
[2].rm_so
, NULL
, 16);
261 if (b
> e
) /* skip */
264 /* seq->first is already less than slot, so just leave it */
265 seq
->count
= e
- b
+ 1;
268 * The fmt string contains the characters before the bracket, the
269 * a format specifier (either decimal or hex) and any characters
270 * after the bracket. Note that the length of the lower range is
271 * use as a minimum digit length, with zero fill, so the format
272 * specifier will look something like %03d.
274 sprintf(seq
->fmt
, "%.*s%%0%d%c%s",
275 (int)bracket
.rm_so
, tty
.ty_name
,
276 (int)(match
[1].rm_eo
- match
[1].rm_so
),
278 tty
.ty_name
+ bracket
.rm_eo
);
281 if (newslot
> slot
) {
282 /* set up to skip until newslot */
283 seq
->first
= newslot
;
286 if (seq
->count
> 0) /* restart if we are doing a sequence */
288 /* regular single value return */
296 * Skip over the current field, removing quotes, and return a pointer to
306 for (q
= 0, t
= p
; (c
= *p
) != '\0'; p
++) {
308 q
^= QUOTED
; /* obscure, but nice */
311 if (q
== QUOTED
&& *p
== '\\' && *(p
+1) == '"')
321 if (c
== '\t' || c
== ' ' || c
== '\n') {
324 while ((c
= *p
) == '\t' || c
== ' ' || c
== '\n')
338 return ((p
= index(p
, '=')) ? ++p
: NULL
);
345 /* initialize seq and the three regexp patterns */
347 if (regcomp(&brapreg
, brapat
, REG_EXTENDED
) != 0)
349 if (regcomp(&decpreg
, decpat
, REG_EXTENDED
) != 0) {
353 if (regcomp(&hexpreg
, hexpat
, REG_EXTENDED
| REG_ICASE
) != 0) {
358 if ((seq
= malloc(sizeof(struct seq
))) == NULL
) {
365 seq
->first
= seq
->count
= 0;
371 } else if ((tf
= fopen(_PATH_TTYS
, "r")) != NULL
)
382 rval
= !(fclose(tf
) == EOF
);