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