]> git.decadent.org.uk Git - nfs-utils.git/blob - support/nfs/xio.c
Fix version fallback for unmount.
[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), 0644)) < 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 (c == '"') {
99                         quoted = !quoted;
100                         continue;
101                 }
102                 tok[i++] = c;
103                 if (i >= 4 &&
104                     tok[i-4] == '\\' &&
105                     isoctal(tok[i-3]) &&
106                     isoctal(tok[i-2]) &&
107                     isoctal(tok[i-1]) &&
108                     ((tok[i]=0),
109                      (c = strtol(tok+i-3,NULL, 8)) < 256)) {
110                         i -= 4;
111                         tok[i++] = c;
112                 }
113         }       
114         if (c == '\n')
115                 xungetc(c, xfp);
116         if (!i)
117                 return 0;
118         if (i >= len || (sepa && c != sepa))
119                 return -1;
120         tok[i] = '\0';
121         return 1;
122 }
123
124 int
125 xgetc(XFILE *xfp)
126 {
127         int     c = getc(xfp->x_fp);
128
129         if (c == EOF)
130                 return c;
131         if (c == '\\') {
132                 if ((c = getc(xfp->x_fp)) != '\n') {
133                         ungetc(c, xfp->x_fp);
134                         return '\\';
135                 }
136                 xfp->x_line++;
137                 while ((c = getc(xfp->x_fp)) == ' ' || c == '\t');
138                 ungetc(c, xfp->x_fp);
139                 return ' ';
140         }
141         if (c == '\n')
142                 xfp->x_line++;
143         return c;
144 }
145
146 void
147 xungetc(int c, XFILE *xfp)
148 {
149         if (c == EOF)
150                 return;
151
152         ungetc(c, xfp->x_fp);
153         if (c == '\n')
154                 xfp->x_line--;
155 }
156
157 void
158 xskip(XFILE *xfp, char *str)
159 {
160         int     c;
161
162         while ((c = xgetc(xfp)) != EOF) {
163                 if (c == '#')
164                         c = xskipcomment(xfp);
165                 if (strchr(str, c) == NULL)
166                         break;
167         }
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 }