A cvsup file that pulls the "checked out" version of source. I'm referencing
[dragonfly.git] / sbin / rconfig / subs.c
blob5b204bcc2327dec141b81b54722180edbb66bd44
1 /*
2 * RCONFIG/SUBS.C
4 * $DragonFly: src/sbin/rconfig/subs.c,v 1.2 2004/06/19 16:03:01 dillon Exp $
5 */
7 #include "defs.h"
9 static void udp_alarm(int signo);
11 static __inline
12 int
13 iswhite(char c)
15 return(c == ' ' || c == '\t' || c == '\r' || c == '\n');
18 const char *
19 parse_str(char **scanp, int flags)
21 char *base;
22 char *ptr;
24 for (base = *scanp; *base && iswhite(*base); ++base)
26 for (ptr = base; *ptr && !iswhite(*ptr); ++ptr) {
27 if (flags & PAS_ALPHA) {
28 if ((*ptr >= 'a' && *ptr <= 'z') ||
29 (*ptr >= 'A' && *ptr <= 'Z') ||
30 *ptr == '_'
31 ) {
32 continue;
35 if (flags & PAS_NUMERIC) {
36 if (*ptr >= '0' && *ptr <= '9')
37 continue;
39 if ((flags & PAS_ANY) == 0)
40 return(NULL);
42 if (*ptr)
43 *ptr++ = 0;
44 *scanp = ptr;
45 return(base);
48 int
49 udp_transact(struct sockaddr_in *sain, struct sockaddr_in *rsin, int *pfd,
50 char **bufp, int *lenp, const char *ctl, ...)
52 va_list va;
53 int fd;
54 int n;
55 int rsin_len = sizeof(*rsin);
56 int rc;
57 int nretry = 3;
58 int timeout = 1;
59 int on = 1;
60 char buf[2048];
62 if (*bufp) {
63 free(*bufp);
64 *bufp = NULL;
65 *lenp = 0;
67 if ((fd = *pfd) < 0) {
68 struct sockaddr_in lsin;
70 lsin.sin_addr.s_addr = INADDR_ANY;
71 lsin.sin_port = 0;
72 lsin.sin_family = AF_INET;
73 if ((fd = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC)) < 0) {
74 asprintf(bufp, "udp_transaction: socket: %s", strerror(errno));
75 *lenp = strlen(*bufp);
76 return(509);
78 setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
79 if (bind(fd, (void *)&lsin, sizeof(lsin)) < 0) {
80 asprintf(bufp, "udp_transaction: bind: %s", strerror(errno));
81 *lenp = strlen(*bufp);
82 close(fd);
83 return(509);
85 *pfd = fd;
87 retry:
88 va_start(va, ctl);
89 vsnprintf(buf, sizeof(buf), ctl, va);
90 va_end(va);
91 if (sendto(fd, buf, strlen(buf), 0, (void *)sain, sizeof(*sain)) >= 0) {
92 struct sigaction nact;
93 struct sigaction oact;
95 bzero(&nact, sizeof(nact));
96 nact.sa_handler = udp_alarm;
97 nact.sa_flags = 0;
98 sigaction(SIGALRM, &nact, &oact);
99 alarm(timeout);
100 n = recvfrom(fd, buf, sizeof(buf) - 1, 0, (void *)rsin, &rsin_len);
101 alarm(0);
102 sigaction(SIGALRM, &oact, NULL);
103 if (n < 0) {
104 if (errno == EINTR && --nretry > 0)
105 goto retry;
106 asprintf(bufp, "udp_transaction: recvfrom: timeout");
107 *lenp = strlen(*bufp);
108 return(508);
110 while (n > 0 && (buf[n - 1] == '\r' || buf[n - 1] == '\n'))
111 --n;
112 buf[n] = 0;
113 rc = strtol(buf, NULL, 10);
114 *bufp = strdup(buf);
115 *lenp = strlen(buf);
116 } else {
117 rc = 508;
118 asprintf(bufp, "udp_transaction: sendto: %s", strerror(errno));
119 *lenp = strlen(*bufp);
121 return(rc);
125 tcp_transact(struct sockaddr_in *sain, FILE **pfi, FILE **pfo, char **bufp,
126 int *lenp, const char *ctl, ...)
128 char buf[2048];
129 va_list va;
130 int rc;
131 int n;
133 if (*bufp) {
134 free(*bufp);
135 *bufp = NULL;
137 if (*pfi == NULL) {
138 int fd;
140 if ((fd = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
141 asprintf(bufp, "tcp_transaction: socket: %s", strerror(errno));
142 *lenp = strlen(*bufp);
143 return(509);
145 if (connect(fd, (void *)sain, sizeof(*sain)) < 0) {
146 asprintf(bufp, "tcp_transaction: connect: %s", strerror(errno));
147 *lenp = strlen(*bufp);
148 close(fd);
149 return(509);
151 *pfi = fdopen(fd, "r");
152 *pfo = fdopen(dup(fd), "w");
153 if (tcp_transact(sain, pfi, pfo, bufp, lenp, NULL) != 108) {
154 fclose(*pfi);
155 fclose(*pfo);
156 *pfi = *pfo = NULL;
157 if (*bufp)
158 free(*bufp);
159 asprintf(bufp, "tcp_transaction: did not get HELLO from server\n");
160 *lenp = strlen(*bufp);
161 return(509);
163 if (*bufp) {
164 printf("%s\n", *bufp);
165 free(*bufp);
166 *bufp = NULL;
169 if (ctl) {
170 va_start(va, ctl);
171 vfprintf(*pfo, ctl, va);
172 va_end(va);
173 fflush(*pfo);
175 if (fgets(buf, sizeof(buf), *pfi) != NULL) {
176 rc = strtol(buf, NULL, 10);
177 n = strlen(buf);
178 if (rc == 201 && strstr(buf, "SIZE=") != NULL) {
179 *lenp = strtol(strstr(buf, "SIZE=") + 5, NULL, 0);
180 if (*lenp > 0)
181 *bufp = malloc(*lenp);
182 for (rc = 0; *bufp && rc < *lenp; rc += n) {
183 if ((n = *lenp - rc) > sizeof(buf))
184 n = sizeof(buf);
185 n = fread(*bufp + rc, 1, n, *pfi);
186 if (n <= 0)
187 break;
189 if (rc == *lenp && fgets(buf, sizeof(buf), *pfi)) {
190 if (strstr(buf, "ERROR=")) {
191 rc = strtol(strstr(buf, "ERROR=") + 6, NULL, 0);
192 if (rc == 0)
193 rc = 201;
194 else
195 rc = 509;
196 } else {
197 rc = 509;
199 } else {
200 rc = 509;
202 if (rc != 201) {
203 free(*bufp);
204 asprintf(bufp, "tcp_transaction: download failed\n");
205 *lenp = strlen(*bufp);
207 } else {
208 while (n > 0 && (buf[n-1] == '\r' || buf[n-1] == '\n'))
209 --n;
210 buf[n] = 0;
211 *bufp = strdup(buf);
212 *lenp = n;
214 } else {
215 asprintf(bufp, "tcp_transaction: read: %s", strerror(errno));
216 *lenp = strlen(*bufp);
217 fclose(*pfi);
218 fclose(*pfo);
219 *pfi = *pfo = NULL;
220 rc = 509;
222 return(rc);
225 static
226 void
227 udp_alarm(int signo)
229 /* do nothing */