]>
Commit | Line | Data |
---|---|---|
090089c4 | 1 | #include "config.h" |
2 | ||
3 | #include <stdio.h> | |
4 | #include <stdlib.h> | |
5 | #include <unistd.h> | |
6 | #include <string.h> | |
7 | #include <sys/types.h> | |
8 | #include <sys/socket.h> | |
9 | #include <netinet/in.h> | |
10 | #include <arpa/inet.h> | |
11 | #include <netdb.h> | |
12 | ||
13 | #include "util.h" | |
14 | ||
15 | char *databuf = NULL; | |
16 | int quiet = 0; | |
17 | int debug = 0; | |
18 | char *announce_to_host = "sd.cache.nlanr.net"; | |
19 | int announce_to_port = 3131; | |
20 | ||
21 | int http_port = CACHE_HTTP_PORT; | |
22 | int icp_port = CACHE_ICP_PORT; | |
23 | ||
24 | ||
25 | int read_config(fname) | |
26 | char *fname; | |
27 | { | |
28 | FILE *fp = NULL; | |
29 | char buf[BUFSIZ]; | |
30 | char munge[BUFSIZ]; | |
31 | char *t = NULL; | |
32 | char *tag = NULL; | |
33 | char *w_space = " \t\n"; | |
34 | ||
35 | if ((fp = fopen(fname, "r")) == (FILE *) NULL) | |
36 | return 0; | |
37 | ||
38 | while (fgets(buf, BUFSIZ, fp)) { | |
39 | if ((t = strchr(buf, '#'))) | |
40 | *t = '\0'; | |
41 | if (buf[0] == '\0') | |
42 | continue; | |
43 | strcpy(munge, buf); | |
44 | if ((tag = strtok(munge, w_space)) == NULL) | |
45 | continue; | |
46 | if (!strcasecmp(tag, "cache_announce")) { | |
47 | if ((t = strtok(NULL, w_space)) == NULL) | |
48 | exit(0); | |
49 | if (strcasecmp(t, "on")) | |
50 | exit(0); | |
51 | } else if (!strcasecmp(tag, "announce_to")) { | |
52 | if ((t = strtok(NULL, w_space)) == NULL) | |
53 | continue; | |
54 | announce_to_host = xstrdup(t); | |
55 | if ((t = strchr(announce_to_host, ':'))) { | |
56 | announce_to_port = atoi(t + 1); | |
57 | *t = '\0'; | |
58 | } | |
59 | } else if (!strncasecmp(tag, "announce_", 9)) { | |
60 | strcat(databuf, buf); | |
61 | } else if (!strcasecmp(tag, "ascii_port")) { | |
62 | if ((t = strtok(NULL, w_space))) | |
63 | http_port = atoi(t); | |
64 | } else if (!strcasecmp(tag, "udp_port")) { | |
65 | if ((t = strtok(NULL, w_space))) | |
66 | icp_port = atoi(t); | |
67 | } | |
68 | } | |
69 | fclose(fp); | |
70 | return 1; | |
71 | } | |
72 | ||
73 | ||
74 | int send_packet(host, port) | |
75 | char *host; | |
76 | int port; | |
77 | { | |
78 | char buf[256]; | |
79 | time_t t; | |
80 | int s; | |
81 | struct sockaddr_in R; | |
82 | struct sockaddr_in L; | |
83 | struct hostent *hp = NULL; | |
84 | ||
85 | sprintf(buf, "cache_version HARVEST/%s\n", HARVEST_VERSION); | |
86 | strcat(databuf, buf); | |
87 | sprintf(buf, "Running on %s %d %d\n", | |
88 | getfullhostname(), | |
89 | http_port, | |
90 | icp_port); | |
91 | strcat(databuf, buf); | |
92 | t = time(NULL); | |
93 | sprintf(buf, "generated %d [%s]\n", | |
94 | (int) t, mkhttpdlogtime(&t)); | |
95 | strcat(databuf, buf); | |
96 | ||
97 | if ((hp = gethostbyname(host)) == NULL) { | |
98 | if (!quiet) | |
99 | fprintf(stderr, "%s: Unknown host\n", host); | |
100 | return 0; | |
101 | } | |
102 | memset(&L, '\0', sizeof(L)); | |
103 | L.sin_family = AF_INET; | |
104 | L.sin_port = 0; | |
105 | L.sin_addr.s_addr = INADDR_ANY; | |
106 | ||
107 | if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { | |
108 | if (!quiet) | |
109 | perror("socket"); | |
110 | return 0; | |
111 | } | |
112 | if (bind(s, (struct sockaddr *) &L, sizeof(L)) < 0) { | |
113 | if (!quiet) | |
114 | perror("bind"); | |
115 | return 0; | |
116 | } | |
117 | memset(&R, '\0', sizeof(R)); | |
118 | R.sin_family = AF_INET; | |
119 | R.sin_port = htons(port); | |
120 | memcpy(&R.sin_addr, hp->h_addr_list[0], 4); | |
121 | ||
122 | if (debug) { | |
123 | close(s); | |
124 | printf("This would be sent to %s [%s] port %d\n", | |
125 | host, inet_ntoa(R.sin_addr), port); | |
126 | puts(databuf); | |
127 | return 0; | |
128 | } | |
129 | if (sendto(s, databuf, strlen(databuf), 0, (struct sockaddr *) &R, sizeof(R)) < 0) { | |
130 | if (!quiet) | |
131 | perror(host); | |
132 | return 0; | |
133 | } | |
134 | close(s); | |
135 | return 1; | |
136 | } | |
137 | ||
138 | ||
139 | main(argc, argv) | |
140 | int argc; | |
141 | char *argv[]; | |
142 | ||
143 | { | |
144 | char config[256]; | |
145 | char *s = NULL; | |
146 | int c; | |
147 | extern int optind; | |
148 | while ((c = getopt(argc, argv, "dqh")) != -1) { | |
149 | switch (c) { | |
150 | case 'd': | |
151 | debug = 1; | |
152 | break; | |
153 | case 'q': | |
154 | quiet = 1; | |
155 | break; | |
156 | case 'h': | |
157 | fprintf(stderr, "usage: %s -d -q -h [cached.conf]\n", | |
158 | argv[0]); | |
159 | exit(0); | |
160 | break; | |
161 | } | |
162 | } | |
163 | argv += (optind - 1); | |
164 | argc -= (optind - 1); | |
165 | ||
166 | if (argc > 1) { | |
167 | strcpy(config, argv[1]); | |
168 | } else if ((s = getenv("HARVEST_HOME"))) { | |
169 | sprintf(config, "%s/lib/cached.conf", s); | |
170 | } else { | |
171 | strcpy(config, "/usr/local/harvest/lib/cached.conf"); | |
172 | } | |
173 | ||
174 | databuf = (char *) xcalloc(8192, 1); | |
175 | if (!read_config(config)) { | |
176 | if (!quiet) | |
177 | perror(config); | |
178 | exit(1); | |
179 | } | |
180 | send_packet(announce_to_host, announce_to_port); | |
181 | return 0; | |
182 | } |