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