Fix typo in previous change.
[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 = 0;
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)) < 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 int
87 xgettok(XFILE *xfp, char sepa, char *tok, int len)
88 {
89         int     i = 0;
90         char    c = 0;
91
92         while (i < len && (c = xgetc(xfp)) != EOF && c != sepa && !isspace(c))
93                 tok[i++] = c;
94         if (c == '\n')
95                 xungetc(c, xfp);
96         if (!i)
97                 return 0;
98         if (i >= len || (sepa && c != sepa))
99                 return -1;
100         tok[i] = '\0';
101         return 1;
102 }
103
104 char
105 xgetc(XFILE *xfp)
106 {
107         char    c = getc(xfp->x_fp);
108
109         if (c == EOF)
110                 return c;
111         if (c == '\\') {
112                 if ((c = getc(xfp->x_fp)) != '\n') {
113                         ungetc(c, xfp->x_fp);
114                         return '\\';
115                 }
116                 xfp->x_line++;
117                 while ((c = getc(xfp->x_fp)) == ' ' || c == '\t');
118                 ungetc(c, xfp->x_fp);
119                 return ' ';
120         }
121         if (c == '#')
122                 c = xskipcomment(xfp);
123         if (c == '\n')
124                 xfp->x_line++;
125         return c;
126 }
127
128 void
129 xungetc(int c, XFILE *xfp)
130 {
131         if (c == EOF)
132                 return;
133
134         ungetc(c, xfp->x_fp);
135         if (c == '\n')
136                 xfp->x_line--;
137 }
138
139 void
140 xskip(XFILE *xfp, char *str)
141 {
142         char    c;
143
144         while ((c = xgetc(xfp)) != EOF && strchr(str, c));
145         ungetc(c, xfp->x_fp);
146 }
147
148 char
149 xskipcomment(XFILE *xfp)
150 {
151         char    c;
152
153         while ((c = getc(xfp->x_fp)) != EOF && c != '\n');
154         return c;
155 }