Change machien to machine.
[dragonfly.git] / sbin / rconfig / client.c
1 /*
2  * RCONFIG/CLIENT.C
3  *
4  * $DragonFly: src/sbin/rconfig/client.c,v 1.2 2004/06/18 04:26:53 dillon Exp $
5  */
6
7 #include "defs.h"
8
9 #define LONG_ALIGN(n)   (((n) + (sizeof(long) - 1)) & ~(sizeof(long) - 1))
10
11 static void load_client_broadcast_tags(tag_t tag, const char *tagName);
12
13 void
14 doClient(void)
15 {
16     int done = 0;
17     tag_t tag;
18
19     /*
20      * The server list is in the form host[:tag]
21      */
22     chdir(WorkDir);
23     for (tag = AddrBase; tag && !done; tag = tag->next) {
24         struct sockaddr_in sain;
25         struct sockaddr_in rsin;
26         char *tagName;
27         char *host = NULL;
28         char *res = NULL;
29         char *buf = NULL;
30         int len;
31         int ufd = -1;
32         FILE *fi = NULL;
33         FILE *fo = NULL;
34         int rc;
35
36         bzero(&sain, sizeof(sain));
37         if (tag->name == NULL) {
38             load_client_broadcast_tags(tag, "auto");
39             continue;
40         }
41         if (tag->name[0] == ':') {
42             load_client_broadcast_tags(tag, tag->name + 1);
43             continue;
44         }
45         host = strdup(tag->name);
46         if ((tagName = strchr(host, ':')) != NULL)
47             *tagName++ = 0;
48         else
49             tagName = "auto";
50         tagName = strdup(tagName);
51         if (inet_aton(host, &sain.sin_addr) == 0) {
52             struct hostent *hp;
53             if ((hp = gethostbyname2(host, AF_INET)) == NULL) {
54                 fprintf(stderr, "Unable to resolve %s\n", host);
55                 exit(1);
56             }
57             bcopy(hp->h_addr_list[0], &sain.sin_addr, hp->h_length);
58             free(host);
59             host = strdup(hp->h_name);
60             endhostent();
61         }
62         sain.sin_port = htons(257);
63         sain.sin_len = sizeof(sain);
64         sain.sin_family = AF_INET;
65
66         /*
67          * Do a couple of UDP transactions to locate the tag on the server.
68          */
69         printf("%s:%s - ", host, tagName);
70         fflush(stdout);
71         rc = udp_transact(&sain, &rsin, &ufd, &res, &len, "TAG %s\r\n", tagName);
72         if (rc != 101 || res == NULL) {
73             printf("NO LUCK %s\n", (res ? res : ""));
74         } else {
75             printf("%s -", res);
76             fflush(stdout);
77             rc = tcp_transact(&rsin, &fi, &fo, &buf, &len, "TAG %s\r\n", tagName);
78             if (rc == 201 && buf) {
79                 int ffd;
80                 char *path;
81
82                 asprintf(&path, "%s/%s.sh", WorkDir, tagName);
83                 ffd = open(path, O_CREAT|O_TRUNC|O_RDWR, 0755);
84                 if (ffd >= 0 && write(ffd, buf, len) == len) {
85                     printf("running %s [%d] in", path, len);
86                     close(ffd);
87                     ffd = -1;
88                     for (rc = 5; rc > 0; --rc) {
89                         printf(" %d", rc);
90                         fflush(stdout);
91                         sleep(1);
92                     }
93                     printf(" 0\n");
94                     fflush(stdout);
95                     rc = system(path);
96                     if (rc)
97                         printf("rconfig script exit code %d\n", rc);
98                     done = 1;
99                 } else {
100                     if (ffd >= 0) {
101                         remove(path);
102                         close(ffd);
103                         ffd = -1;
104                     }
105                     printf(" unable to create %s [%d] - DOWNLOAD FAILED\n",
106                             path, len);
107                 }
108             } else {
109                 printf(" DOWNLOAD FAILED\n");
110             }
111         }
112         if (ufd >= 0) {
113             close(ufd);
114             ufd = -1;
115         }
116         if (fi != NULL) {
117             fclose(fi);
118             fi = NULL;
119         }
120         if (fo != NULL) {
121             fclose(fo);
122             fo = NULL;
123         }
124         if (buf)
125             free(buf);
126         if (res)
127             free(res);
128         free(host);
129         free(tagName);
130     }
131 }
132
133 static
134 void
135 load_client_broadcast_tags(tag_t tag, const char *tagName)
136 {
137     struct sockaddr_dl *sdl;
138     struct if_msghdr *ifm;
139     int mib[6];
140     char *buf;
141     int bytes;
142     int i;
143
144     mib[0] = CTL_NET;
145     mib[1] = PF_ROUTE;
146     mib[2] = 0;
147     mib[3] = AF_INET;
148     mib[4] = NET_RT_IFLIST;
149     mib[5] = 0;
150
151     if (sysctl(mib, 6, NULL, &bytes, NULL, 0) < 0) {
152         printf("no interfaces!\n");
153         exit(1);
154     }
155     buf = malloc(bytes);
156     if (sysctl(mib, 6, buf, &bytes, NULL, 0) < 0) {
157         printf("no interfaces!\n");
158         exit(1);
159     }
160     ifm = (void *)buf;
161     sdl = NULL;
162     while ((char *)ifm < buf + bytes && ifm->ifm_msglen) {
163         switch(ifm->ifm_type) {
164         case RTM_IFINFO:
165             if (ifm->ifm_flags & IFF_UP) {
166                 sdl = (void *)(ifm + 1);
167             } else {
168                 sdl = NULL;
169             }
170             break;
171         case RTM_NEWADDR:
172             if (sdl) {
173                 struct sockaddr_in *sain;
174                 struct ifa_msghdr *ifam;
175                 char *scan;
176                 char *name;
177                 tag_t ntag;
178
179                 ifam = (void *)ifm;
180                 scan = (char *)(ifam + 1);
181                 for (i = 0; i < RTAX_MAX; ++i) {
182                     if ((1 << i) & ifam->ifam_addrs) {
183                         sain = (void *)scan;
184                         if (i == RTAX_BRD) {
185                             asprintf(&name, "%s:%s",
186                                     inet_ntoa(sain->sin_addr), tagName);
187                             ntag = calloc(sizeof(struct tag), 1);
188                             ntag->name = name;
189                             ntag->flags = 0;
190                             ntag->next = tag->next;
191                             tag->next = ntag;
192                             tag = ntag;
193                             if (VerboseOpt)
194                                 printf("add: %s (%s)\n", sdl->sdl_data, tag->name);
195                         }
196                         scan = scan + LONG_ALIGN(sain->sin_len);
197                     }
198                 }
199             }
200             break;
201         }
202         ifm = (void *)((char *)ifm + ifm->ifm_msglen);
203     }
204 }
205