[8507] | 1 | #ifndef SOCK_H
|
---|
| 2 | #define SOCK_H
|
---|
| 3 |
|
---|
[8879] | 4 | int sockwrite(int fd, unsigned char* buf, int count, int tout)
|
---|
[8878] | 5 | {
|
---|
| 6 | struct timeval timeout;
|
---|
[10569] | 7 | int ret = 0, usec = 0, sec = 0, tmpcount = count;
|
---|
[8879] | 8 | unsigned char* buffer = NULL;
|
---|
[8507] | 9 |
|
---|
[8879] | 10 | if(fd < 0) return -1;
|
---|
| 11 |
|
---|
[10357] | 12 | if(tout == -1) tout = 3000 * 1000;
|
---|
[10569] | 13 | usec = tout % 1000000;
|
---|
| 14 | sec = (tout - usec) / 1000000;
|
---|
[9111] | 15 |
|
---|
[8878] | 16 | fd_set wfds;
|
---|
| 17 |
|
---|
| 18 | while (tmpcount > 0)
|
---|
| 19 | {
|
---|
| 20 | buffer = buf + (count - tmpcount);
|
---|
| 21 | ret = send(fd, buffer, tmpcount, MSG_DONTWAIT | MSG_NOSIGNAL);
|
---|
[9049] | 22 | if(ret < 0)
|
---|
[8878] | 23 | {
|
---|
[9049] | 24 | if(errno == EINTR || errno == EAGAIN)
|
---|
[8878] | 25 | {
|
---|
[9049] | 26 | FD_ZERO(&wfds);
|
---|
| 27 | FD_SET(fd, &wfds);
|
---|
[8878] | 28 |
|
---|
[10569] | 29 | timeout.tv_sec = sec;
|
---|
| 30 | timeout.tv_usec = usec;
|
---|
[8878] | 31 |
|
---|
[10380] | 32 | ret = TEMP_FAILURE_RETRY(select(fd + 1, NULL, &wfds, NULL, &timeout));
|
---|
[9049] | 33 | }
|
---|
[8878] | 34 |
|
---|
| 35 | if(ret == 0)
|
---|
| 36 | {
|
---|
[10357] | 37 | perr("sock send timed out fd=%d", fd);
|
---|
[8878] | 38 | return -1;
|
---|
| 39 | }
|
---|
[9049] | 40 | if(ret < 0)
|
---|
[8878] | 41 | {
|
---|
[10357] | 42 | perr("sock send data fd=%d", fd);
|
---|
[8878] | 43 | return -1;
|
---|
| 44 | }
|
---|
| 45 | }
|
---|
| 46 | else
|
---|
| 47 | tmpcount -= ret;
|
---|
| 48 | }
|
---|
[8944] | 49 |
|
---|
[8878] | 50 | return count;
|
---|
| 51 | }
|
---|
| 52 |
|
---|
[10381] | 53 | //flag 0: normal
|
---|
| 54 | //flag 1: from check
|
---|
| 55 | int sockread(int fd, unsigned char *buf, int pos, int count, int tout, int flag)
|
---|
[8507] | 56 | {
|
---|
[8878] | 57 | struct timeval timeout;
|
---|
[10569] | 58 | int ret = 0, usec = 0, sec = 0, tmpcount = count;
|
---|
[8879] | 59 | unsigned char* buffer = NULL;
|
---|
[8878] | 60 |
|
---|
[8879] | 61 | if(fd < 0) return -1;
|
---|
| 62 |
|
---|
[10357] | 63 | if(tout == -1) tout = 3000 * 1000;
|
---|
[10569] | 64 | usec = tout % 1000000;
|
---|
| 65 | sec = (tout - usec) / 1000000;
|
---|
[9111] | 66 |
|
---|
[8878] | 67 | fd_set rfds;
|
---|
| 68 |
|
---|
| 69 | while(tmpcount > 0)
|
---|
[8507] | 70 | {
|
---|
[8878] | 71 | FD_ZERO(&rfds);
|
---|
| 72 | FD_SET(fd, &rfds);
|
---|
| 73 |
|
---|
[10569] | 74 | timeout.tv_sec = sec;
|
---|
| 75 | timeout.tv_usec = usec;
|
---|
[8878] | 76 |
|
---|
[10380] | 77 | ret = TEMP_FAILURE_RETRY(select(fd + 1, &rfds , NULL, NULL, &timeout));
|
---|
[8878] | 78 |
|
---|
| 79 | if(ret == 1)
|
---|
| 80 | {
|
---|
| 81 | buffer = buf + (count - tmpcount);
|
---|
[10566] | 82 | retry:
|
---|
[8878] | 83 | ret = recv(fd, buffer, tmpcount, MSG_DONTWAIT | MSG_NOSIGNAL);
|
---|
[8933] | 84 | if(ret == 0) //connection closed
|
---|
| 85 | {
|
---|
[9230] | 86 | if(count - tmpcount != 0) return count - tmpcount;
|
---|
[23091] | 87 | debug(250, "connection closed fd=%d, count=%d", fd, count - tmpcount);
|
---|
[10381] | 88 | if(flag == 1) return -1;
|
---|
| 89 | return 0;
|
---|
[8933] | 90 | }
|
---|
[8878] | 91 | if(ret < 0) //error
|
---|
| 92 | {
|
---|
[10569] | 93 | if(errno == EAGAIN && tout > 0)
|
---|
| 94 | {
|
---|
| 95 | tout = tout - 1000;
|
---|
| 96 | usleep(1000);
|
---|
| 97 | goto retry;
|
---|
| 98 | }
|
---|
[10357] | 99 | perr("sock read data fd=%d", fd);
|
---|
[8878] | 100 | return ret;
|
---|
| 101 | }
|
---|
| 102 | else
|
---|
| 103 | tmpcount -= ret;
|
---|
| 104 | }
|
---|
[10357] | 105 | else if(ret == 0)
|
---|
| 106 | {
|
---|
| 107 | debug(250, "sock timeout fd=%d", fd);
|
---|
| 108 | return ret;
|
---|
| 109 | }
|
---|
[8878] | 110 | else
|
---|
[10357] | 111 | {
|
---|
| 112 | perr("sock select fd=%d", fd);
|
---|
[8933] | 113 | return ret;
|
---|
[10357] | 114 | }
|
---|
[8507] | 115 | }
|
---|
[8878] | 116 | return count;
|
---|
[8507] | 117 | }
|
---|
| 118 |
|
---|
[9012] | 119 | void sockclose(int *fd)
|
---|
[8933] | 120 | {
|
---|
[9012] | 121 | if(*fd != -1)
|
---|
| 122 | close(*fd);
|
---|
| 123 | *fd = -1;
|
---|
| 124 | }
|
---|
| 125 |
|
---|
| 126 | int sockcheck(int *fd)
|
---|
| 127 | {
|
---|
[8933] | 128 | int ret = 0;
|
---|
| 129 | unsigned char buf[1];
|
---|
| 130 |
|
---|
[9012] | 131 | if(*fd < 0) return 1;
|
---|
[8933] | 132 |
|
---|
[10381] | 133 | ret = sockread(*fd, buf, 0, 1, 0, 1);
|
---|
[8933] | 134 | if(ret < 0)
|
---|
[9012] | 135 | {
|
---|
| 136 | sockclose(fd);
|
---|
[8933] | 137 | return 1;
|
---|
[9012] | 138 | }
|
---|
[8933] | 139 |
|
---|
| 140 | return 0;
|
---|
| 141 | }
|
---|
| 142 |
|
---|
[9230] | 143 | int sockportopen(int *fd, char* ip, int port, int tout)
|
---|
| 144 | {
|
---|
| 145 | int ret = 0, rest = 0, optval;
|
---|
| 146 | socklen_t optlen = sizeof(optval);
|
---|
| 147 | struct timeval timeout;
|
---|
| 148 | struct sockaddr_in cliaddr;
|
---|
[14415] | 149 |
|
---|
| 150 | if(ip == NULL) return 1;
|
---|
| 151 | sockclose(fd);
|
---|
[9230] | 152 |
|
---|
| 153 | memset(&cliaddr, 0, sizeof(struct sockaddr_in));
|
---|
| 154 | cliaddr.sin_family = AF_INET;
|
---|
| 155 | cliaddr.sin_port = htons(port);
|
---|
| 156 |
|
---|
| 157 | if((*fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
|
---|
| 158 | {
|
---|
| 159 | perr("open port socket");
|
---|
| 160 | return 1;
|
---|
| 161 | }
|
---|
| 162 |
|
---|
| 163 | ret = inet_pton(AF_INET, ip, (void *)(&(cliaddr.sin_addr.s_addr)));
|
---|
| 164 | if(ret < 0)
|
---|
| 165 | {
|
---|
| 166 | sockclose(fd);
|
---|
| 167 | perr("Can't set remote->sin_addr.s_addr");
|
---|
| 168 | return 1;
|
---|
| 169 | }
|
---|
| 170 | else if(ret == 0)
|
---|
| 171 | {
|
---|
| 172 | sockclose(fd);
|
---|
[14407] | 173 | err("%s is not a valid IP address", ip);
|
---|
[9230] | 174 | return 1;
|
---|
| 175 | }
|
---|
| 176 |
|
---|
| 177 | fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK);
|
---|
| 178 |
|
---|
[10357] | 179 | if(tout == -1) tout = 3000 * 1000;
|
---|
[9230] | 180 | rest = tout % 1000000;
|
---|
| 181 | tout = (tout - rest) / 1000000;
|
---|
| 182 |
|
---|
| 183 | fd_set wfds;
|
---|
| 184 |
|
---|
| 185 | ret = connect(*fd, (struct sockaddr*) &cliaddr, sizeof(struct sockaddr));
|
---|
| 186 | if(ret < 0)
|
---|
| 187 | {
|
---|
| 188 | if(errno == EINTR || errno == EINPROGRESS)
|
---|
| 189 | {
|
---|
| 190 | FD_ZERO(&wfds);
|
---|
| 191 | FD_SET(*fd, &wfds);
|
---|
| 192 |
|
---|
| 193 | timeout.tv_sec = tout;
|
---|
| 194 | timeout.tv_usec = rest;
|
---|
| 195 |
|
---|
[10380] | 196 | ret = TEMP_FAILURE_RETRY(select(*fd + 1, NULL, &wfds, NULL, &timeout));
|
---|
[9230] | 197 |
|
---|
| 198 | if(ret == 1 && FD_ISSET(*fd, &wfds))
|
---|
| 199 | {
|
---|
| 200 | ret = getsockopt(*fd, SOL_SOCKET, SO_ERROR, &optval, &optlen);
|
---|
| 201 | if(ret == -1)
|
---|
| 202 | {
|
---|
| 203 | sockclose(fd);
|
---|
| 204 | return 1;
|
---|
| 205 | }
|
---|
| 206 | if(optval == 0) return 0;
|
---|
| 207 | sockclose(fd);
|
---|
| 208 | return 1;
|
---|
| 209 | }
|
---|
| 210 | }
|
---|
| 211 |
|
---|
| 212 | if(ret <= 0)
|
---|
| 213 | {
|
---|
| 214 | perr("connect");
|
---|
| 215 | sockclose(fd);
|
---|
| 216 | return 1;
|
---|
| 217 | }
|
---|
| 218 | }
|
---|
| 219 | return 0;
|
---|
| 220 | }
|
---|
| 221 |
|
---|
[9049] | 222 | int sockopen(int *fd, char* sockname, int check, int tout)
|
---|
[8507] | 223 | {
|
---|
[8879] | 224 | sockclose(fd);
|
---|
[8507] | 225 |
|
---|
[9111] | 226 | int ret = 0, rest = 0, optval;
|
---|
[9049] | 227 | socklen_t optlen = sizeof(optval);
|
---|
| 228 | struct timeval timeout;
|
---|
[8507] | 229 | struct sockaddr_un servaddr;
|
---|
[8878] | 230 | socklen_t len;
|
---|
[8507] | 231 |
|
---|
| 232 | memset(&servaddr, 0, sizeof(struct sockaddr_un));
|
---|
| 233 | servaddr.sun_family = AF_UNIX;
|
---|
| 234 | strncpy(servaddr.sun_path, sockname, sizeof(servaddr.sun_path) - 1);
|
---|
| 235 | servaddr.sun_path[sizeof(servaddr.sun_path) - 1] = '\0';
|
---|
[8878] | 236 | len = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
|
---|
[8507] | 237 |
|
---|
[8878] | 238 | if((*fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
|
---|
[8507] | 239 | {
|
---|
[8933] | 240 | if(check == 0)
|
---|
| 241 | {
|
---|
| 242 | perr("open socket");
|
---|
| 243 | }
|
---|
[8507] | 244 | return 1;
|
---|
| 245 | }
|
---|
| 246 |
|
---|
[9049] | 247 | fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK);
|
---|
| 248 |
|
---|
[10357] | 249 | if(tout == -1) tout = 3000 * 1000;
|
---|
[9111] | 250 | rest = tout % 1000000;
|
---|
| 251 | tout = (tout - rest) / 1000000;
|
---|
| 252 |
|
---|
[9049] | 253 | fd_set wfds;
|
---|
| 254 |
|
---|
| 255 | ret = connect(*fd, (struct sockaddr*) &servaddr, len);
|
---|
| 256 | if(ret < 0)
|
---|
[8507] | 257 | {
|
---|
[9049] | 258 | if(errno == EINTR || errno == EINPROGRESS)
|
---|
[8933] | 259 | {
|
---|
[9049] | 260 | FD_ZERO(&wfds);
|
---|
| 261 | FD_SET(*fd, &wfds);
|
---|
| 262 |
|
---|
[9111] | 263 | timeout.tv_sec = tout;
|
---|
| 264 | timeout.tv_usec = rest;
|
---|
[9049] | 265 |
|
---|
[10380] | 266 | ret = TEMP_FAILURE_RETRY(select(*fd + 1, NULL, &wfds, NULL, &timeout));
|
---|
[9049] | 267 |
|
---|
| 268 | if(ret == 1 && FD_ISSET(*fd, &wfds))
|
---|
| 269 | {
|
---|
| 270 | ret = getsockopt(*fd, SOL_SOCKET, SO_ERROR, &optval, &optlen);
|
---|
[9230] | 271 | if(ret == -1)
|
---|
| 272 | {
|
---|
| 273 | sockclose(fd);
|
---|
| 274 | return 1;
|
---|
| 275 | }
|
---|
[9049] | 276 | if(optval == 0) return 0;
|
---|
[9230] | 277 | sockclose(fd);
|
---|
[9049] | 278 | return 1;
|
---|
| 279 | }
|
---|
[8933] | 280 | }
|
---|
[9049] | 281 |
|
---|
| 282 | if(ret <= 0)
|
---|
| 283 | {
|
---|
| 284 | if(check == 0)
|
---|
| 285 | {
|
---|
| 286 | perr("connect");
|
---|
| 287 | }
|
---|
| 288 | sockclose(fd);
|
---|
| 289 | return 1;
|
---|
| 290 | }
|
---|
[8507] | 291 | }
|
---|
| 292 | return 0;
|
---|
| 293 | }
|
---|
| 294 |
|
---|
[9212] | 295 | int sockportcreate(int *fd, int port, int maxconn)
|
---|
[8944] | 296 | {
|
---|
| 297 | struct sockaddr_in servaddr;
|
---|
| 298 | servaddr.sin_family = AF_INET;
|
---|
| 299 | servaddr.sin_port = htons(port);
|
---|
| 300 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
---|
| 301 | int sockoptactive = 1, ret = 0;
|
---|
| 302 |
|
---|
| 303 | if(!port) return 1;
|
---|
| 304 |
|
---|
| 305 | if((*fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
---|
| 306 | {
|
---|
| 307 | perr("open socket");
|
---|
| 308 | return 1;
|
---|
| 309 | }
|
---|
| 310 |
|
---|
| 311 | if(setsockopt(*fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&sockoptactive, sizeof (int)) < 0)
|
---|
| 312 | {
|
---|
| 313 | perr("network port %u open: error setsockopt", port);
|
---|
| 314 |
|
---|
| 315 | sockclose(fd);
|
---|
| 316 | return 1;
|
---|
| 317 | }
|
---|
| 318 |
|
---|
| 319 | while(1)
|
---|
| 320 | {
|
---|
| 321 | ret = bind(*fd, &servaddr, sizeof(servaddr));
|
---|
| 322 | if(ret < 0)
|
---|
| 323 | {
|
---|
| 324 | if(errno == EINTR) continue;
|
---|
| 325 | perr("bind");
|
---|
| 326 | sockclose(fd);
|
---|
| 327 | return 1;
|
---|
| 328 | }
|
---|
| 329 | break;
|
---|
| 330 | }
|
---|
| 331 |
|
---|
| 332 | while(1)
|
---|
| 333 | {
|
---|
[9212] | 334 | ret = listen(*fd, maxconn);
|
---|
[8944] | 335 | if(ret < 0)
|
---|
| 336 | {
|
---|
| 337 | if(errno == EINTR) continue;
|
---|
| 338 | perr("listen");
|
---|
| 339 | sockclose(fd);
|
---|
| 340 | return 1;
|
---|
| 341 | }
|
---|
| 342 | break;
|
---|
| 343 | }
|
---|
| 344 |
|
---|
| 345 | return ret;
|
---|
| 346 | }
|
---|
| 347 |
|
---|
[9212] | 348 | int sockcreate(int *fd, char* sockname, int maxconn)
|
---|
[8507] | 349 | {
|
---|
[8879] | 350 | sockclose(fd);
|
---|
[8507] | 351 |
|
---|
| 352 | struct sockaddr_un servaddr;
|
---|
[8878] | 353 | socklen_t len;
|
---|
| 354 | int ret = 0;
|
---|
[8507] | 355 |
|
---|
| 356 | memset(&servaddr, 0, sizeof(struct sockaddr_un));
|
---|
| 357 | servaddr.sun_family = AF_UNIX;
|
---|
| 358 | strncpy(servaddr.sun_path, sockname, sizeof(servaddr.sun_path) - 1);
|
---|
| 359 | servaddr.sun_path[sizeof(servaddr.sun_path) - 1] = '\0';
|
---|
[8878] | 360 | len = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
|
---|
[8507] | 361 | unlink(servaddr.sun_path);
|
---|
| 362 |
|
---|
[8878] | 363 | if((*fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
|
---|
[8507] | 364 | {
|
---|
| 365 | perr("open socket");
|
---|
| 366 | return 1;
|
---|
| 367 | }
|
---|
| 368 |
|
---|
| 369 | while(1)
|
---|
| 370 | {
|
---|
[8878] | 371 | ret = bind(*fd, &servaddr, len);
|
---|
[8507] | 372 | if(ret < 0)
|
---|
| 373 | {
|
---|
| 374 | if(errno == EINTR) continue;
|
---|
| 375 | perr("bind");
|
---|
[8879] | 376 | sockclose(fd);
|
---|
[8507] | 377 | return 1;
|
---|
| 378 | }
|
---|
| 379 | break;
|
---|
| 380 | }
|
---|
| 381 |
|
---|
| 382 | while(1)
|
---|
| 383 | {
|
---|
[9212] | 384 | ret = listen(*fd, maxconn);
|
---|
[8507] | 385 | if(ret < 0)
|
---|
| 386 | {
|
---|
| 387 | if(errno == EINTR) continue;
|
---|
| 388 | perr("listen");
|
---|
[8879] | 389 | sockclose(fd);
|
---|
[8507] | 390 | return 1;
|
---|
| 391 | }
|
---|
| 392 | break;
|
---|
| 393 | }
|
---|
| 394 |
|
---|
[8878] | 395 | return ret;
|
---|
[8507] | 396 | }
|
---|
| 397 |
|
---|
[8944] | 398 | //flag 0 = in blocking mode
|
---|
| 399 | //flag 1 = in non blocking mode
|
---|
| 400 | int sockaccept(int *fd, int flag)
|
---|
[8507] | 401 | {
|
---|
[9212] | 402 | struct sockaddr_in cliaddr;
|
---|
| 403 | socklen_t clilen = sizeof(cliaddr);
|
---|
[8878] | 404 | int ret = 0;
|
---|
[8507] | 405 |
|
---|
[8944] | 406 | if(*fd < 0) return -1;
|
---|
| 407 |
|
---|
| 408 | while(1)
|
---|
[8507] | 409 | {
|
---|
[8933] | 410 | ret = accept(*fd, &cliaddr, &clilen);
|
---|
[8878] | 411 | if(ret < 0)
|
---|
| 412 | {
|
---|
| 413 | if(errno == EINTR) continue;
|
---|
| 414 | perr("accept");
|
---|
[9049] | 415 | if(flag == 0 || (flag == 1 && errno != EAGAIN))
|
---|
| 416 | sockclose(fd);
|
---|
[8944] | 417 | return -1;
|
---|
[8878] | 418 | }
|
---|
| 419 | break;
|
---|
[8507] | 420 | }
|
---|
| 421 |
|
---|
[8878] | 422 | return ret;
|
---|
[8507] | 423 | }
|
---|
| 424 |
|
---|
[8933] | 425 | int socksend(int *fd, unsigned char* data, int count, int timeout)
|
---|
[8507] | 426 | {
|
---|
[8878] | 427 | int ret = 0;
|
---|
[8507] | 428 |
|
---|
[8933] | 429 | if(*fd == -1) return 1;
|
---|
[8878] | 430 |
|
---|
[8933] | 431 | ret = sockwrite(*fd, data, count, timeout);
|
---|
[8878] | 432 | if(ret < 0)
|
---|
[8507] | 433 | {
|
---|
[8933] | 434 | sockclose(fd);
|
---|
[8507] | 435 | return 1;
|
---|
| 436 | }
|
---|
| 437 | return 0;
|
---|
| 438 | }
|
---|
| 439 |
|
---|
[8933] | 440 | int sockreceive(int *fd, unsigned char* data, int count, int timeout)
|
---|
[8507] | 441 | {
|
---|
[8878] | 442 | int ret = 0;
|
---|
[8507] | 443 |
|
---|
[8933] | 444 | if(*fd == -1) return 1;
|
---|
[8507] | 445 |
|
---|
[10381] | 446 | ret = sockread(*fd, data, 0, count, timeout, 0);
|
---|
[9132] | 447 | if(ret <= 0)
|
---|
[8878] | 448 | {
|
---|
[8933] | 449 | sockclose(fd);
|
---|
[8878] | 450 | return 1;
|
---|
| 451 | }
|
---|
[8507] | 452 | return 0;
|
---|
| 453 | }
|
---|
| 454 |
|
---|
| 455 | char *get_ip(char *host)
|
---|
| 456 | {
|
---|
[14597] | 457 | struct hostent hent;
|
---|
| 458 | struct hostent *result = NULL;
|
---|
[20466] | 459 | int ret = 0, err = 0, iplen = 16, ext = 0;
|
---|
| 460 | char *ip = NULL, *buf = NULL, *tmpstr = NULL;
|
---|
[8507] | 461 |
|
---|
[9230] | 462 | if(host == NULL) return NULL;
|
---|
| 463 |
|
---|
[19467] | 464 | ip = calloc(1, iplen);
|
---|
[8507] | 465 | if(ip == NULL)
|
---|
| 466 | {
|
---|
| 467 | err("no mem");
|
---|
| 468 | return NULL;
|
---|
| 469 | }
|
---|
| 470 |
|
---|
[19467] | 471 | buf = calloc(1, MINMALLOC);
|
---|
[14597] | 472 | if(buf == NULL)
|
---|
[8507] | 473 | {
|
---|
[14597] | 474 | err("no mem");
|
---|
[8507] | 475 | free(ip);
|
---|
[14597] | 476 | return NULL;
|
---|
| 477 | }
|
---|
| 478 |
|
---|
| 479 | ret = gethostbyname_r(host, &hent, buf, MINMALLOC, &result, &err);
|
---|
| 480 | //if((hent = gethostbyname(host)) == NULL)
|
---|
| 481 | if(ret != 0 || result == NULL)
|
---|
| 482 | {
|
---|
[20469] | 483 | free(ip); ip = NULL;
|
---|
| 484 | free(buf); buf = NULL;
|
---|
[20466] | 485 | //workaround: if resolv.conf is changed, titan mußt stopped, so gethostbyname read resolv.conf new
|
---|
| 486 | //the external tool read resolv.conf on each start
|
---|
| 487 | err("can't get ip, test with extern tool (%s)", host);
|
---|
| 488 |
|
---|
[20468] | 489 | tmpstr = ostrcat("getip ", host, 0, 0);
|
---|
[20466] | 490 | ip = command(tmpstr);
|
---|
| 491 | free(tmpstr); tmpstr = NULL;
|
---|
| 492 | if(ip == NULL)
|
---|
| 493 | {
|
---|
| 494 | err("can't get ip (%s)", host);
|
---|
| 495 | return NULL;
|
---|
| 496 | }
|
---|
| 497 | ext = 1;
|
---|
[8507] | 498 | }
|
---|
| 499 |
|
---|
| 500 | //snprintf(ip, iplen, "%s", inet_ntoa(*((struct in_addr*)hent->h_addr)));
|
---|
[14597] | 501 | //snprintf(ip, iplen, "%s", inet_ntoa(*((struct in_addr*)result->h_addr)));
|
---|
[20466] | 502 |
|
---|
| 503 | if(ext == 0)
|
---|
[8507] | 504 | {
|
---|
[20466] | 505 | //if(inet_ntop(AF_INET, (void *)hent->h_addr_list[0], ip, iplen) == NULL)
|
---|
| 506 | if(inet_ntop(AF_INET, (void *)result->h_addr_list[0], ip, iplen) == NULL)
|
---|
| 507 | {
|
---|
| 508 | free(ip);
|
---|
| 509 | free(buf);
|
---|
| 510 | perr("can't resolve host");
|
---|
| 511 | return NULL;
|
---|
| 512 | }
|
---|
[8507] | 513 | }
|
---|
| 514 |
|
---|
[14597] | 515 | free(buf);
|
---|
[8507] | 516 | return ip;
|
---|
| 517 | }
|
---|
| 518 |
|
---|
[12866] | 519 | char* createhttpheader(char *host, char *page, char* auth)
|
---|
[8507] | 520 | {
|
---|
[12866] | 521 | char *query = NULL;
|
---|
[8507] | 522 | char *getpage = page;
|
---|
| 523 |
|
---|
[18397] | 524 | if(getpage != NULL)
|
---|
| 525 | {
|
---|
| 526 | if(getpage[0] == '/')
|
---|
| 527 | getpage = getpage + 1;
|
---|
| 528 | }
|
---|
[12866] | 529 |
|
---|
| 530 | query = ostrcat("GET /", getpage, 0, 0);
|
---|
[19036] | 531 | query = ostrcat(query, " HTTP/1.0\r\nHost: ", 1, 0);
|
---|
[12866] | 532 | query = ostrcat(query, host, 1, 0);
|
---|
| 533 | query = ostrcat(query, "\r\nUser-Agent: ", 1, 0);
|
---|
[18368] | 534 | //query = ostrcat(query, PROGNAME, 1, 0);
|
---|
[18369] | 535 | query = ostrcat(query, "Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.99 Safari/535.1", 1, 0);
|
---|
[12866] | 536 | if(auth != NULL)
|
---|
[8507] | 537 | {
|
---|
[12866] | 538 | query = ostrcat(query, "\r\nAuthorization: Basic ", 1, 0);
|
---|
| 539 | query = ostrcat(query, auth, 1, 0);
|
---|
[8507] | 540 | }
|
---|
[18356] | 541 | query = ostrcat(query, "\r\nConnection: close", 1, 0);
|
---|
[12866] | 542 | query = ostrcat(query, "\r\n\r\n", 1, 0);
|
---|
[9230] | 543 |
|
---|
[8507] | 544 | return query;
|
---|
| 545 | }
|
---|
| 546 |
|
---|
[14073] | 547 | int checkhttpheader(char* tmpbuf, char** retstr)
|
---|
[8507] | 548 | {
|
---|
[14073] | 549 | int stat = 0;
|
---|
| 550 | char* tmppos = NULL, *tmpstr = NULL;
|
---|
| 551 |
|
---|
[14573] | 552 | if(tmpbuf == NULL) return 0;
|
---|
[14073] | 553 |
|
---|
| 554 | tmpstr = malloc(MINMALLOC);
|
---|
| 555 | if(tmpstr == NULL)
|
---|
| 556 | {
|
---|
| 557 | err("no mem");
|
---|
| 558 | return 0;
|
---|
| 559 | }
|
---|
| 560 |
|
---|
[16471] | 561 | tmppos = ostrstr(tmpbuf, "HTTP/1.1 ");
|
---|
[14073] | 562 | if(tmppos != NULL)
|
---|
| 563 | {
|
---|
| 564 | sscanf(tmppos, "HTTP/1.1 %s ", tmpstr);
|
---|
| 565 | if(tmpstr != NULL)
|
---|
| 566 | {
|
---|
| 567 | stat = atoi(tmpstr);
|
---|
| 568 | tmpstr[0] = '\0';
|
---|
| 569 | }
|
---|
| 570 | }
|
---|
| 571 |
|
---|
[14475] | 572 | if(stat == 301 || stat == 302) // Redirect
|
---|
[14073] | 573 | {
|
---|
[16471] | 574 | tmppos = ostrstr(tmpbuf, "Location: ");
|
---|
[14073] | 575 | if(tmppos != NULL)
|
---|
| 576 | {
|
---|
| 577 | sscanf(tmppos, "Location: %s", tmpstr);
|
---|
| 578 | if(tmpstr != NULL)
|
---|
| 579 | *retstr = ostrcat(tmpstr, NULL, 0, 0);
|
---|
| 580 | }
|
---|
| 581 | }
|
---|
| 582 |
|
---|
| 583 | free(tmpstr); tmpstr = NULL;
|
---|
| 584 | return stat;
|
---|
| 585 | }
|
---|
| 586 |
|
---|
[18366] | 587 | //flag 0: output without header
|
---|
| 588 | //flag 1: output with header
|
---|
[24220] | 589 | //flag 2: output only header
|
---|
[19839] | 590 | char* gethttpreal(char* host, char* page, int port, char* filename, char* auth, struct download* dnode, int redirect, char* header, long* clen, int timeout, int flag)
|
---|
[14073] | 591 | {
|
---|
[17832] | 592 | int sock = -1, ret = 0, count = 0, hret = 0, freeheader = 0;
|
---|
[18366] | 593 | int headerlen = 0;
|
---|
[9230] | 594 | unsigned int len = 0, maxret = 0;
|
---|
[17832] | 595 | char *ip = NULL;
|
---|
[8507] | 596 | char *tmpbuf = NULL, *buf = NULL;
|
---|
[14073] | 597 | char *tmppage = "/", *retstr = NULL;
|
---|
[8507] | 598 | FILE *fd = NULL;
|
---|
| 599 |
|
---|
| 600 | if(filename != NULL)
|
---|
| 601 | {
|
---|
| 602 | fd = fopen(filename, "wb");
|
---|
| 603 | if(fd == NULL)
|
---|
| 604 | {
|
---|
[14407] | 605 | err("can't open file %s", filename);
|
---|
[9230] | 606 | if(dnode != NULL) dnode->ret = 1;
|
---|
[8507] | 607 | return NULL;
|
---|
| 608 | }
|
---|
| 609 | }
|
---|
| 610 |
|
---|
[9230] | 611 | if(page == NULL) page = tmppage;
|
---|
[8507] | 612 |
|
---|
| 613 | ip = get_ip(host);
|
---|
| 614 | if(ip == NULL)
|
---|
| 615 | {
|
---|
[14407] | 616 | err("can't get ip");
|
---|
[8507] | 617 | if(fd != NULL)
|
---|
| 618 | {
|
---|
| 619 | fclose(fd);
|
---|
| 620 | unlink(filename);
|
---|
| 621 | }
|
---|
[9230] | 622 | if(dnode != NULL) dnode->ret = 1;
|
---|
[8507] | 623 | return NULL;
|
---|
| 624 | }
|
---|
| 625 |
|
---|
[19839] | 626 | ret = sockportopen(&sock, ip, port, timeout * 1000);
|
---|
[9230] | 627 | if(ret != 0)
|
---|
[8507] | 628 | {
|
---|
| 629 | if(fd != NULL)
|
---|
| 630 | {
|
---|
| 631 | fclose(fd);
|
---|
| 632 | unlink(filename);
|
---|
| 633 | }
|
---|
[9230] | 634 | free(ip);
|
---|
| 635 | if(dnode != NULL) dnode->ret = 1;
|
---|
[8507] | 636 | return NULL;
|
---|
| 637 | }
|
---|
[9230] | 638 | free(ip);
|
---|
| 639 |
|
---|
| 640 | if(dnode != NULL) dnode->connfd = sock;
|
---|
[17832] | 641 | if(header == NULL)
|
---|
| 642 | {
|
---|
| 643 | header = createhttpheader(host, page, auth);
|
---|
| 644 | freeheader = 1;
|
---|
| 645 | }
|
---|
[9230] | 646 |
|
---|
| 647 | //Send the query to the server
|
---|
[19839] | 648 | ret = socksend(&sock, (unsigned char*)header, strlen(header), timeout * 1000);
|
---|
[9230] | 649 | if(ret != 0)
|
---|
[8507] | 650 | {
|
---|
[9230] | 651 | perr("can't send query");
|
---|
[8507] | 652 | if(fd != NULL)
|
---|
| 653 | {
|
---|
| 654 | fclose(fd);
|
---|
| 655 | unlink(filename);
|
---|
| 656 | }
|
---|
[17832] | 657 | if(freeheader == 1) free(header);
|
---|
[9230] | 658 | if(dnode != NULL) dnode->ret = 1;
|
---|
[8507] | 659 | return NULL;
|
---|
| 660 | }
|
---|
[17832] | 661 | if(freeheader == 1) free(header);
|
---|
[15948] | 662 |
|
---|
[9230] | 663 | //now it is time to receive the page
|
---|
[19467] | 664 | tmpbuf = calloc(1, MINMALLOC);
|
---|
[9230] | 665 | if(tmpbuf == NULL)
|
---|
[8507] | 666 | {
|
---|
| 667 | if(fd != NULL)
|
---|
| 668 | {
|
---|
| 669 | fclose(fd);
|
---|
| 670 | unlink(filename);
|
---|
| 671 | }
|
---|
[9230] | 672 | sockclose(&sock);
|
---|
| 673 | err("no mem");
|
---|
| 674 | if(dnode != NULL) dnode->ret = 1;
|
---|
[8507] | 675 | return NULL;
|
---|
| 676 | }
|
---|
| 677 |
|
---|
[9230] | 678 | //read one line
|
---|
| 679 | char* pbuf = tmpbuf;
|
---|
| 680 | while(pbuf - tmpbuf < MINMALLOC)
|
---|
| 681 | {
|
---|
| 682 | unsigned char c;
|
---|
[8507] | 683 |
|
---|
[19839] | 684 | ret = sockreceive(&sock, &c, 1, timeout * 1000);
|
---|
[9230] | 685 | if(ret != 0)
|
---|
[8507] | 686 | {
|
---|
[9230] | 687 | err("no client data in buffer");
|
---|
| 688 | break;
|
---|
[8507] | 689 | }
|
---|
[9230] | 690 |
|
---|
| 691 | *pbuf = c;
|
---|
[18366] | 692 | headerlen++;
|
---|
[9230] | 693 |
|
---|
[16492] | 694 | if(tmpbuf != NULL && (ostrstr(tmpbuf, "\n\n") != NULL || ostrstr(tmpbuf, "\r\n\r\n") != NULL))
|
---|
[14073] | 695 | {
|
---|
| 696 | hret = checkhttpheader(tmpbuf, &retstr);
|
---|
[14475] | 697 | if(hret == 301 || hret == 302) goto end;
|
---|
[9230] | 698 | break;
|
---|
[14073] | 699 | }
|
---|
[9230] | 700 | pbuf++;
|
---|
[8507] | 701 | }
|
---|
| 702 |
|
---|
[24220] | 703 | if(flag == 3)
|
---|
| 704 | {
|
---|
| 705 | if(headerlen > 0)
|
---|
| 706 | {
|
---|
| 707 | count = headerlen;
|
---|
| 708 | headerlen = 0;
|
---|
| 709 | if(filename != NULL)
|
---|
| 710 | fwrite(tmpbuf, count, 1, fd);
|
---|
| 711 | else
|
---|
| 712 | {
|
---|
| 713 | buf = realloc(buf, count);
|
---|
| 714 | memcpy(buf, tmpbuf, count);
|
---|
| 715 | }
|
---|
| 716 | }
|
---|
| 717 |
|
---|
| 718 | goto end;
|
---|
| 719 | }
|
---|
| 720 |
|
---|
[9230] | 721 | //TODO: case-sens check
|
---|
[16471] | 722 | char* contentlen = ostrstr(tmpbuf, "Content-Length:");
|
---|
[9230] | 723 | if(contentlen != NULL)
|
---|
[8507] | 724 | {
|
---|
[9230] | 725 | contentlen += 15;
|
---|
| 726 | len = strtoul(contentlen, NULL, 10);
|
---|
[8507] | 727 | }
|
---|
| 728 |
|
---|
[18366] | 729 | if(flag == 0) headerlen = 0;
|
---|
[19839] | 730 | while((ret = sockread(sock, (unsigned char*)tmpbuf + headerlen, 0, MINMALLOC - headerlen, timeout * 1000, 0)) > 0)
|
---|
[8507] | 731 | {
|
---|
[9230] | 732 | maxret += ret;
|
---|
| 733 | if(len > 0)
|
---|
[8507] | 734 | {
|
---|
[9230] | 735 | if(dnode != NULL)
|
---|
[8507] | 736 | {
|
---|
[9230] | 737 | dnode->proz = (int)ceil((((float)maxret / len) * 100));
|
---|
| 738 | dnode->maxkb = len;
|
---|
| 739 | dnode->aktkb = maxret;
|
---|
[8507] | 740 | }
|
---|
| 741 | }
|
---|
[9230] | 742 |
|
---|
[18366] | 743 | ret += headerlen;
|
---|
| 744 | headerlen = 0;
|
---|
[9230] | 745 | if(filename != NULL)
|
---|
| 746 | fwrite(tmpbuf, ret, 1, fd);
|
---|
[8507] | 747 | else
|
---|
| 748 | {
|
---|
[9230] | 749 | count = count + ret;
|
---|
| 750 | buf = realloc(buf, count);
|
---|
| 751 | memcpy(buf + count - ret, tmpbuf, ret);
|
---|
[8507] | 752 | }
|
---|
[9230] | 753 | memset(tmpbuf, 0, ret);
|
---|
[8507] | 754 | }
|
---|
[9230] | 755 | if(ret < 0)
|
---|
[8507] | 756 | {
|
---|
[9230] | 757 | perr("receiving data");
|
---|
[8507] | 758 | if(fd != NULL)
|
---|
| 759 | {
|
---|
| 760 | fclose(fd);
|
---|
| 761 | unlink(filename);
|
---|
| 762 | }
|
---|
[9230] | 763 | sockclose(&sock);
|
---|
| 764 | free(buf);
|
---|
| 765 | free(tmpbuf);
|
---|
| 766 | if(dnode != NULL) dnode->ret = 1;
|
---|
[21620] | 767 |
|
---|
[8507] | 768 | return NULL;
|
---|
| 769 | }
|
---|
| 770 |
|
---|
[14073] | 771 | end:
|
---|
[8507] | 772 | free(tmpbuf);
|
---|
| 773 | if(fd != NULL) fclose(fd);
|
---|
[9230] | 774 | sockclose(&sock);
|
---|
[8507] | 775 |
|
---|
| 776 | if(filename == NULL)
|
---|
| 777 | {
|
---|
| 778 | buf = realloc(buf, count + 1);
|
---|
| 779 | buf[count] = '\0';
|
---|
| 780 | }
|
---|
| 781 |
|
---|
[14475] | 782 | if((hret == 301 || hret == 302) && retstr != NULL && redirect < 3) //redirect
|
---|
[14073] | 783 | {
|
---|
| 784 | char* pos = NULL, *rpage = NULL;
|
---|
[18356] | 785 | char* rhost = NULL;
|
---|
[14073] | 786 |
|
---|
[18356] | 787 | if(strchr(retstr, '/') == retstr)
|
---|
[14073] | 788 | {
|
---|
[18356] | 789 | rhost = ostrcat(host, NULL, 0, 0);
|
---|
| 790 | rpage = retstr;
|
---|
[14073] | 791 | }
|
---|
[18356] | 792 | else
|
---|
| 793 | {
|
---|
| 794 | rhost = string_replace("http://", "", retstr, 0);
|
---|
[14073] | 795 |
|
---|
[18356] | 796 | if(rhost != NULL)
|
---|
| 797 | pos = strchr(rhost, '/');
|
---|
| 798 | if(pos != NULL)
|
---|
| 799 | {
|
---|
| 800 | pos[0] = '\0';
|
---|
| 801 | rpage = pos + 1;
|
---|
| 802 | }
|
---|
[14073] | 803 | }
|
---|
| 804 |
|
---|
| 805 | redirect++;
|
---|
| 806 | free(buf); buf = NULL;
|
---|
[19839] | 807 | buf = gethttpreal(rhost, rpage, port, filename, auth, dnode, redirect, NULL, clen, timeout, flag);
|
---|
[18356] | 808 | free(rhost); rhost = NULL;
|
---|
[14073] | 809 | }
|
---|
| 810 |
|
---|
[17832] | 811 | if(clen != 0) *clen = maxret;
|
---|
[9230] | 812 | if(dnode != NULL) dnode->ret = 0;
|
---|
[14073] | 813 | free(retstr); retstr = NULL;
|
---|
[21620] | 814 |
|
---|
| 815 | if(filename == NULL)
|
---|
| 816 | return buf;
|
---|
| 817 | else
|
---|
| 818 | return "0";
|
---|
[8507] | 819 | }
|
---|
| 820 |
|
---|
[19884] | 821 | char* gethttp(char* host, char* page, int port, char* filename, char* auth, int timeout, struct download* dnode, int redirect)
|
---|
[17832] | 822 | {
|
---|
[19884] | 823 | return gethttpreal(host, page, port, filename, auth, dnode, redirect, NULL, NULL, timeout, 0);
|
---|
[17832] | 824 | }
|
---|
| 825 |
|
---|
[9230] | 826 | void gethttpstruct(struct stimerthread* timernode, struct download* node, int flag)
|
---|
| 827 | {
|
---|
| 828 | if(node != NULL)
|
---|
[19884] | 829 | gethttp(node->host, node->page, node->port, node->filename, node->auth, node->timeout, node, 0);
|
---|
[9230] | 830 | }
|
---|
| 831 |
|
---|
[20906] | 832 | void gethttpstructmsg(struct stimerthread* timernode, struct download* node, int flag)
|
---|
| 833 | {
|
---|
| 834 | char* tmpstr = NULL;
|
---|
| 835 |
|
---|
| 836 | if(node != NULL)
|
---|
| 837 | {
|
---|
| 838 | gethttp(node->host, node->page, node->port, node->filename, node->auth, node->timeout, node, 0);
|
---|
| 839 | tmpstr = ostrcat(_("Download finished!"), "\n\n", 0, 0);
|
---|
| 840 | tmpstr = ostrcat(tmpstr, node->filename, 1, 0);
|
---|
| 841 | textbox(_("Message"), tmpstr, _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 1100, 300, 7, 0);
|
---|
| 842 |
|
---|
| 843 | free(tmpstr); tmpstr = NULL;
|
---|
| 844 | }
|
---|
| 845 | }
|
---|
| 846 |
|
---|
[20736] | 847 | int sendmail(char* host, char* mailfrom, char* mailto, char* subject, int port, char* filename, char* string, int rtimeout, int wtimeout)
|
---|
| 848 | {
|
---|
| 849 | int sock = -1, ret = 0;
|
---|
| 850 | char *ip = NULL, *tmpstr = NULL, *sendstr = NULL, *data = NULL;
|
---|
| 851 |
|
---|
| 852 | if(filename == NULL && string == NULL) return 1;
|
---|
| 853 |
|
---|
| 854 | ip = get_ip(host);
|
---|
| 855 | if(ip == NULL)
|
---|
| 856 | {
|
---|
| 857 | err("can't get ip");
|
---|
| 858 | return 1;
|
---|
| 859 | }
|
---|
| 860 |
|
---|
| 861 | data = malloc(MINMALLOC);
|
---|
| 862 | if(data == NULL)
|
---|
| 863 | {
|
---|
| 864 | err("no memory");
|
---|
| 865 | return 1;
|
---|
| 866 | }
|
---|
| 867 |
|
---|
| 868 | if(filename != NULL)
|
---|
| 869 | tmpstr = readfiletomem(filename, 0);
|
---|
| 870 | else if(string != NULL)
|
---|
| 871 | tmpstr = string;
|
---|
| 872 |
|
---|
| 873 | //open connection
|
---|
| 874 | ret = sockportopen(&sock, ip, port, wtimeout);
|
---|
| 875 | if(ret != 0) goto end;
|
---|
| 876 |
|
---|
| 877 | //wait for smtp answer
|
---|
| 878 | memset(data, 0, MINMALLOC);
|
---|
| 879 | sockread(sock, (unsigned char*)data, 0, MINMALLOC, wtimeout, 0);
|
---|
| 880 | debug(975, "rcv: %s", data);
|
---|
| 881 | /*
|
---|
| 882 | if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
|
---|
| 883 | {
|
---|
| 884 | debug(975, "incorrect answer: %s", data);
|
---|
| 885 | ret = 1;
|
---|
| 886 | goto end;
|
---|
| 887 | }
|
---|
| 888 | */
|
---|
| 889 |
|
---|
| 890 | //send helo
|
---|
| 891 | ret = 1;
|
---|
| 892 | sendstr = ostrcat(sendstr, "HELO nit.at\r\n", 1, 0);
|
---|
| 893 | debug(975, "send: %s", sendstr);
|
---|
| 894 | if(sendstr != NULL)
|
---|
| 895 | ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
|
---|
| 896 | free(sendstr); sendstr = NULL;
|
---|
| 897 | if(ret != 0) goto end;
|
---|
| 898 |
|
---|
| 899 | //wait for smtp answer
|
---|
| 900 | memset(data, 0, MINMALLOC);
|
---|
| 901 | sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
|
---|
| 902 | debug(975, "rcv: %s", data);
|
---|
| 903 | if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
|
---|
| 904 | {
|
---|
| 905 | debug(975, "incorrect answer: %s", data);
|
---|
| 906 | ret = 1;
|
---|
| 907 | goto end;
|
---|
| 908 | }
|
---|
| 909 |
|
---|
| 910 | //send mail from:
|
---|
| 911 | ret = 1;
|
---|
| 912 | sendstr = ostrcat(sendstr, "MAIL FROM:<", 1, 0);
|
---|
| 913 | sendstr = ostrcat(sendstr, mailfrom, 1, 0);
|
---|
| 914 | sendstr = ostrcat(sendstr, ">\r\n", 1, 0);
|
---|
| 915 | debug(975, "send: %s", sendstr);
|
---|
| 916 | if(sendstr != NULL)
|
---|
| 917 | ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
|
---|
| 918 | free(sendstr); sendstr = NULL;
|
---|
| 919 | if(ret != 0) goto end;
|
---|
| 920 |
|
---|
| 921 | //wait for smtp answer
|
---|
| 922 | memset(data, 0, MINMALLOC);
|
---|
| 923 | sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
|
---|
| 924 | debug(975, "rcv: %s", data);
|
---|
| 925 | if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
|
---|
| 926 | {
|
---|
| 927 | debug(975, "incorrect answer: %s", data);
|
---|
| 928 | ret = 1;
|
---|
| 929 | goto end;
|
---|
| 930 | }
|
---|
| 931 |
|
---|
| 932 | //send rcpt to:
|
---|
| 933 | ret = 1;
|
---|
| 934 | sendstr = ostrcat(sendstr, "RCPT TO:<", 1, 0);
|
---|
| 935 | sendstr = ostrcat(sendstr, mailto, 1, 0);
|
---|
| 936 | sendstr = ostrcat(sendstr, ">\r\n", 1, 0);
|
---|
| 937 | debug(975, "send: %s", sendstr);
|
---|
| 938 | if(sendstr != NULL)
|
---|
| 939 | ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
|
---|
| 940 | free(sendstr); sendstr = NULL;
|
---|
| 941 | if(ret != 0) goto end;
|
---|
| 942 |
|
---|
| 943 | //wait for smtp answer
|
---|
| 944 | memset(data, 0, MINMALLOC);
|
---|
| 945 | sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
|
---|
| 946 | debug(975, "rcv: %s", data);
|
---|
| 947 | if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
|
---|
| 948 | {
|
---|
| 949 | debug(975, "incorrect answer: %s", data);
|
---|
| 950 | ret = 1;
|
---|
| 951 | goto end;
|
---|
| 952 | }
|
---|
| 953 |
|
---|
| 954 | //send data
|
---|
| 955 | ret = 1;
|
---|
| 956 | sendstr = ostrcat(sendstr, "DATA\r\n", 1, 0);
|
---|
| 957 | debug(975, "send: %s", sendstr);
|
---|
| 958 | if(sendstr != NULL)
|
---|
| 959 | ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
|
---|
| 960 | free(sendstr); sendstr = NULL;
|
---|
| 961 | if(ret != 0) goto end;
|
---|
| 962 |
|
---|
| 963 | //wait for smtp answer
|
---|
| 964 | memset(data, 0, MINMALLOC);
|
---|
| 965 | sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
|
---|
| 966 | debug(975, "rcv: %s", data);
|
---|
| 967 | if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
|
---|
| 968 | {
|
---|
| 969 | debug(975, "incorrect answer: %s", data);
|
---|
| 970 | ret = 1;
|
---|
| 971 | goto end;
|
---|
| 972 | }
|
---|
| 973 |
|
---|
| 974 | //send content
|
---|
| 975 | ret = 1;
|
---|
| 976 |
|
---|
| 977 | sendstr = ostrcat(sendstr, "From: ", 1, 0);
|
---|
| 978 | sendstr = ostrcat(sendstr, mailfrom, 1, 0);
|
---|
| 979 | sendstr = ostrcat(sendstr, "\r\n", 1, 0);
|
---|
| 980 |
|
---|
| 981 | sendstr = ostrcat(sendstr, "To: ", 1, 0);
|
---|
| 982 | sendstr = ostrcat(sendstr, mailto, 1, 0);
|
---|
| 983 | sendstr = ostrcat(sendstr, "\r\n", 1, 0);
|
---|
| 984 |
|
---|
| 985 | sendstr = ostrcat(sendstr, "Subject: ", 1, 0);
|
---|
| 986 | sendstr = ostrcat(sendstr, subject, 1, 0);
|
---|
| 987 | sendstr = ostrcat(sendstr, "\r\n", 1, 0);
|
---|
| 988 |
|
---|
| 989 | sendstr = ostrcat(sendstr, "Content-Type: text/plain\r\n\r\n", 1, 0);
|
---|
| 990 |
|
---|
| 991 | sendstr = ostrcat(sendstr, tmpstr, 1, 0);
|
---|
| 992 | sendstr = ostrcat(sendstr, "\r\n.\r\n", 1, 0);
|
---|
| 993 |
|
---|
| 994 | debug(975, "send: %s", sendstr);
|
---|
| 995 | if(sendstr != NULL)
|
---|
| 996 | ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
|
---|
| 997 | free(sendstr); sendstr = NULL;
|
---|
| 998 | if(ret != 0) goto end;
|
---|
| 999 |
|
---|
| 1000 | //wait for smtp answer
|
---|
| 1001 | memset(data, 0, MINMALLOC);
|
---|
| 1002 | sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
|
---|
| 1003 | debug(975, "rcv: %s", data);
|
---|
| 1004 | if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
|
---|
| 1005 | {
|
---|
| 1006 | debug(975, "incorrect answer: %s", data);
|
---|
| 1007 | ret = 1;
|
---|
| 1008 | goto end;
|
---|
| 1009 | }
|
---|
| 1010 |
|
---|
| 1011 | //send quit
|
---|
| 1012 | ret = 1;
|
---|
| 1013 | sendstr = ostrcat(sendstr, "QUIT\r\n", 1, 0);
|
---|
| 1014 | debug(975, "send: %s", sendstr);
|
---|
| 1015 | if(sendstr != NULL)
|
---|
| 1016 | ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
|
---|
| 1017 | free(sendstr); sendstr = NULL;
|
---|
| 1018 | if(ret != 0) goto end;
|
---|
| 1019 |
|
---|
| 1020 | //wait for smtp answer
|
---|
| 1021 | memset(data, 0, MINMALLOC);
|
---|
| 1022 | sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
|
---|
| 1023 | debug(975, "rcv: %s", data);
|
---|
| 1024 | if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
|
---|
| 1025 | {
|
---|
| 1026 | debug(975, "incorrect answer: %s", data);
|
---|
| 1027 | ret = 1;
|
---|
| 1028 | goto end;
|
---|
| 1029 | }
|
---|
| 1030 |
|
---|
| 1031 | end:
|
---|
| 1032 | if(filename != NULL)
|
---|
| 1033 | free(tmpstr);
|
---|
| 1034 | tmpstr = NULL;
|
---|
| 1035 | return ret;
|
---|
| 1036 | }
|
---|
| 1037 |
|
---|
[8507] | 1038 | #endif
|
---|