4 * Copyright (c) 2003,2004 The DragonFly Project. All rights reserved.
6 * This code is derived from software contributed to The DragonFly Project
7 * by Matthew Dillon <dillon@backplane.com>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
19 * 3. Neither the name of The DragonFly Project nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific, prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * $DragonFly: src/sbin/rconfig/subs.c,v 1.4 2005/04/02 22:15:20 dillon Exp $
41 static void udp_alarm(int signo
);
47 return(c
== ' ' || c
== '\t' || c
== '\r' || c
== '\n');
51 parse_str(char **scanp
, int flags
)
56 for (base
= *scanp
; *base
&& iswhite(*base
); ++base
)
58 for (ptr
= base
; *ptr
&& !iswhite(*ptr
); ++ptr
) {
59 if (flags
& PAS_ALPHA
) {
60 if ((*ptr
>= 'a' && *ptr
<= 'z') ||
61 (*ptr
>= 'A' && *ptr
<= 'Z') ||
67 if (flags
& PAS_NUMERIC
) {
68 if (*ptr
>= '0' && *ptr
<= '9')
71 if ((flags
& PAS_ANY
) == 0)
81 udp_transact(struct sockaddr_in
*sain
, struct sockaddr_in
*rsin
, int *pfd
,
82 char **bufp
, int *lenp
, const char *ctl
, ...)
87 int rsin_len
= sizeof(*rsin
);
99 if ((fd
= *pfd
) < 0) {
100 struct sockaddr_in lsin
;
102 lsin
.sin_addr
.s_addr
= INADDR_ANY
;
104 lsin
.sin_family
= AF_INET
;
105 if ((fd
= socket(AF_INET
, SOCK_DGRAM
, PF_UNSPEC
)) < 0) {
106 asprintf(bufp
, "udp_transaction: socket: %s", strerror(errno
));
107 *lenp
= strlen(*bufp
);
110 setsockopt(fd
, SOL_SOCKET
, SO_BROADCAST
, &on
, sizeof(on
));
111 if (bind(fd
, (void *)&lsin
, sizeof(lsin
)) < 0) {
112 asprintf(bufp
, "udp_transaction: bind: %s", strerror(errno
));
113 *lenp
= strlen(*bufp
);
121 vsnprintf(buf
, sizeof(buf
), ctl
, va
);
123 if (sendto(fd
, buf
, strlen(buf
), 0, (void *)sain
, sizeof(*sain
)) >= 0) {
124 struct sigaction nact
;
125 struct sigaction oact
;
127 bzero(&nact
, sizeof(nact
));
128 nact
.sa_handler
= udp_alarm
;
130 sigaction(SIGALRM
, &nact
, &oact
);
132 n
= recvfrom(fd
, buf
, sizeof(buf
) - 1, 0, (void *)rsin
, &rsin_len
);
134 sigaction(SIGALRM
, &oact
, NULL
);
136 if (errno
== EINTR
&& --nretry
> 0)
138 asprintf(bufp
, "udp_transaction: recvfrom: timeout");
139 *lenp
= strlen(*bufp
);
142 while (n
> 0 && (buf
[n
- 1] == '\r' || buf
[n
- 1] == '\n'))
145 rc
= strtol(buf
, NULL
, 10);
150 asprintf(bufp
, "udp_transaction: sendto: %s", strerror(errno
));
151 *lenp
= strlen(*bufp
);
157 tcp_transact(struct sockaddr_in
*sain
, FILE **pfi
, FILE **pfo
, char **bufp
,
158 int *lenp
, const char *ctl
, ...)
172 if ((fd
= socket(AF_INET
, SOCK_STREAM
, PF_UNSPEC
)) < 0) {
173 asprintf(bufp
, "tcp_transaction: socket: %s", strerror(errno
));
174 *lenp
= strlen(*bufp
);
177 if (connect(fd
, (void *)sain
, sizeof(*sain
)) < 0) {
178 asprintf(bufp
, "tcp_transaction: connect: %s", strerror(errno
));
179 *lenp
= strlen(*bufp
);
183 *pfi
= fdopen(fd
, "r");
184 *pfo
= fdopen(dup(fd
), "w");
185 if (tcp_transact(sain
, pfi
, pfo
, bufp
, lenp
, NULL
) != 108) {
191 asprintf(bufp
, "tcp_transaction: did not get HELLO from server\n");
192 *lenp
= strlen(*bufp
);
196 printf("%s\n", *bufp
);
203 vfprintf(*pfo
, ctl
, va
);
207 if (fgets(buf
, sizeof(buf
), *pfi
) != NULL
) {
208 rc
= strtol(buf
, NULL
, 10);
210 if (rc
== 201 && strstr(buf
, "SIZE=") != NULL
) {
211 *lenp
= strtol(strstr(buf
, "SIZE=") + 5, NULL
, 0);
213 *bufp
= malloc(*lenp
);
214 for (rc
= 0; *bufp
&& rc
< *lenp
; rc
+= n
) {
215 if ((n
= *lenp
- rc
) > (int)sizeof(buf
))
217 n
= fread(*bufp
+ rc
, 1, n
, *pfi
);
221 if (rc
== *lenp
&& fgets(buf
, sizeof(buf
), *pfi
)) {
222 if (strstr(buf
, "ERROR=")) {
223 rc
= strtol(strstr(buf
, "ERROR=") + 6, NULL
, 0);
236 asprintf(bufp
, "tcp_transaction: download failed\n");
237 *lenp
= strlen(*bufp
);
240 while (n
> 0 && (buf
[n
-1] == '\r' || buf
[n
-1] == '\n'))
247 asprintf(bufp
, "tcp_transaction: read: %s", strerror(errno
));
248 *lenp
= strlen(*bufp
);
259 udp_alarm(int signo __unused
)