]> git.decadent.org.uk Git - nfs-utils.git/blob - support/nfs/xio.c
Now that only the Section names are case-insensitive
[nfs-utils.git] / support / nfs / xio.c
1 /*
2  * support/nfs/xio.c
3  * 
4  * Simple I/O functions for the parsing of /etc/exports and /etc/nfsclients.
5  *
6  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7  */
8
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12
13 #include <sys/fcntl.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <ctype.h>
18 #include <signal.h>
19 #include <unistd.h>
20 #include <errno.h>
21 #include "xmalloc.h"
22 #include "xlog.h"
23 #include "xio.h"
24
25 XFILE *
26 xfopen(char *fname, char *type)
27 {
28         XFILE   *xfp;
29         FILE    *fp;
30
31         if (!(fp = fopen(fname, type)))
32                 return NULL;
33         xfp = (XFILE *) xmalloc(sizeof(*xfp));
34         xfp->x_fp = fp;
35         xfp->x_line = 1;
36
37         return xfp;
38 }
39
40 void
41 xfclose(XFILE *xfp)
42 {
43         fclose(xfp->x_fp);
44         xfree(xfp);
45 }
46
47 static void
48 doalarm(int sig)
49 {
50         return;
51 }
52
53 int
54 xflock(char *fname, char *type)
55 {
56         struct sigaction sa, oldsa;
57         int             readonly = !strcmp(type, "r");
58         struct flock    fl = { readonly? F_RDLCK : F_WRLCK, SEEK_SET, 0, 0, 0 };
59         int             fd;
60
61         if (readonly)
62                 fd = open(fname, (O_RDONLY|O_CREAT), 0600);
63         else
64                 fd = open(fname, (O_RDWR|O_CREAT), 0600);
65         if (fd < 0) {
66                 xlog(L_WARNING, "could not open %s for locking: errno %d (%s)",
67                                 fname, errno, strerror(errno));
68                 return -1;
69         }
70
71         sa.sa_handler = doalarm;
72         sa.sa_flags = 0;
73         sigemptyset(&sa.sa_mask);
74         sigaction(SIGALRM, &sa, &oldsa);
75         alarm(10);
76         if (fcntl(fd, F_SETLKW, &fl) < 0) {
77                 alarm(0);
78                 xlog(L_WARNING, "failed to lock %s: errno %d (%s)",
79                                 fname, errno, strerror(errno));
80                 close(fd);
81                 fd = 0;
82         } else {
83                 alarm(0);
84         }
85         sigaction(SIGALRM, &oldsa, NULL);
86
87         return fd;
88 }
89
90 void
91 xfunlock(int fd)
92 {
93         close(fd);
94 }
95
96 #define isoctal(x) (isdigit(x) && ((x)<'8'))
97 int
98 xgettok(XFILE *xfp, char sepa, char *tok, int len)
99 {
100         int     i = 0;
101         int     c = 0;
102         int     quoted=0;
103
104         while (i < len && (c = xgetc(xfp)) != EOF &&
105                (quoted || (c != sepa && !isspace(c)))) {
106                 if (c == '"') {
107                         quoted = !quoted;
108                         continue;
109                 }
110                 tok[i++] = c;
111                 if (i >= 4 &&
112                     tok[i-4] == '\\' &&
113                     isoctal(tok[i-3]) &&
114                     isoctal(tok[i-2]) &&
115                     isoctal(tok[i-1]) &&
116                     ((tok[i]=0),
117                      (c = strtol(tok+i-3,NULL, 8)) < 256)) {
118                         i -= 4;
119                         tok[i++] = c;
120                 }
121         }       
122         if (c == '\n')
123                 xungetc(c, xfp);
124         if (!i)
125                 return 0;
126         if (i >= len || (sepa && c != sepa))
127                 return -1;
128         tok[i] = '\0';
129         return 1;
130 }
131
132 int
133 xgetc(XFILE *xfp)
134 {
135         int     c = getc(xfp->x_fp);
136
137         if (c == EOF)
138                 return c;
139         if (c == '\\') {
140                 if ((c = getc(xfp->x_fp)) != '\n') {
141                         ungetc(c, xfp->x_fp);
142                         return '\\';
143                 }
144                 xfp->x_line++;
145                 while ((c = getc(xfp->x_fp)) == ' ' || c == '\t');
146                 ungetc(c, xfp->x_fp);
147                 return ' ';
148         }
149         if (c == '\n')
150                 xfp->x_line++;
151         return c;
152 }
153
154 void
155 xungetc(int c, XFILE *xfp)
156 {
157         if (c == EOF)
158                 return;
159
160         ungetc(c, xfp->x_fp);
161         if (c == '\n')
162                 xfp->x_line--;
163 }
164
165 void
166 xskip(XFILE *xfp, char *str)
167 {
168         int     c;
169
170         while ((c = xgetc(xfp)) != EOF) {
171                 if (c == '#')
172                         c = xskipcomment(xfp);
173                 if (strchr(str, c) == NULL)
174                         break;
175         }
176         xungetc(c, xfp);
177 }
178
179 char
180 xskipcomment(XFILE *xfp)
181 {
182         int     c;
183
184         while ((c = getc(xfp->x_fp)) != EOF && c != '\n');
185         return c;
186 }