ftp.c (12661) | ftp.c (15439) |
---|---|
1/* 2 * ---------------------------------------------------------------------------- 3 * "THE BEER-WARE LICENSE" (Revision 42): 4 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you 5 * can do whatever you want with this stuff. If we meet some day, and you think 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7 * ---------------------------------------------------------------------------- 8 * | 1/* 2 * ---------------------------------------------------------------------------- 3 * "THE BEER-WARE LICENSE" (Revision 42): 4 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you 5 * can do whatever you want with this stuff. If we meet some day, and you think 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7 * ---------------------------------------------------------------------------- 8 * |
9 * $Id: ftp.c,v 1.14.2.1 1995/10/21 14:06:35 jkh Exp $ | 9 * $Id: ftp.c,v 1.15 1995/12/07 10:33:47 peter Exp $ |
10 * 11 * Return values have been sanitized: 12 * -1 error, but you (still) have a session. 13 * -2 error, your session is dead. 14 * 15 */ 16 17#include <stdlib.h> --- 26 unchanged lines hidden (view full) --- 44static void 45debug(FTP_t ftp, const char *fmt, ...) 46{ 47 char p[BUFSIZ]; 48 va_list ap; 49 va_start(ap, fmt); 50#ifdef STANDALONE_FTP 51 strcpy(p,"LIBFTP: "); | 10 * 11 * Return values have been sanitized: 12 * -1 error, but you (still) have a session. 13 * -2 error, your session is dead. 14 * 15 */ 16 17#include <stdlib.h> --- 26 unchanged lines hidden (view full) --- 44static void 45debug(FTP_t ftp, const char *fmt, ...) 46{ 47 char p[BUFSIZ]; 48 va_list ap; 49 va_start(ap, fmt); 50#ifdef STANDALONE_FTP 51 strcpy(p,"LIBFTP: "); |
52 (void) vsnprintf(p+strlen(p), sizeof p - strlen(p), fmt, ap); | 52 (void) vsnprintf(p + strlen(p), sizeof p - strlen(p), fmt, ap); |
53 va_end(ap); | 53 va_end(ap); |
54 write(ftp->fd_debug,p,strlen(p)); | 54 write(ftp->fd_debug, p, strlen(p)); |
55#else 56 if (isDebug()) { 57 (void) vsnprintf(p, sizeof p - strlen(p), fmt, ap); 58 msgDebug(p); 59 } 60#endif 61} 62 63static int 64writes(int fd, char *s) 65{ 66 int i = strlen(s); | 55#else 56 if (isDebug()) { 57 (void) vsnprintf(p, sizeof p - strlen(p), fmt, ap); 58 msgDebug(p); 59 } 60#endif 61} 62 63static int 64writes(int fd, char *s) 65{ 66 int i = strlen(s); |
67 if (i != write(fd,s,i)) | 67 if (i != write(fd, s, i)) |
68 return -2; 69 return 0; 70} 71 72static __inline char* 73get_a_line(FTP_t ftp) 74{ 75 static char buf[BUFSIZ]; 76 int i,j; 77 78 for(i=0;i<BUFSIZ;) { | 68 return -2; 69 return 0; 70} 71 72static __inline char* 73get_a_line(FTP_t ftp) 74{ 75 static char buf[BUFSIZ]; 76 int i,j; 77 78 for(i=0;i<BUFSIZ;) { |
79 j = read(ftp->fd_ctrl,buf+i,1); | 79 j = read(ftp->fd_ctrl, buf+i, 1); |
80 if (j != 1) 81 return 0; 82 if (buf[i] == '\r' || buf[i] == '\n') { 83 if (!i) 84 continue; 85 buf[i] = '\0'; | 80 if (j != 1) 81 return 0; 82 if (buf[i] == '\r' || buf[i] == '\n') { 83 if (!i) 84 continue; 85 buf[i] = '\0'; |
86 debug(ftp, "received <%s>\n",buf); | 86 debug(ftp, "received <%s>\n", buf); |
87 return buf; 88 } 89 i++; 90 } 91 return buf; 92} 93 94static int --- 52 unchanged lines hidden (view full) --- 147 char p[BUFSIZ]; 148 int i; 149 150 va_list ap; 151 va_start(ap, fmt); 152 (void) vsnprintf(p, sizeof p, fmt, ap); 153 va_end(ap); 154 | 87 return buf; 88 } 89 i++; 90 } 91 return buf; 92} 93 94static int --- 52 unchanged lines hidden (view full) --- 147 char p[BUFSIZ]; 148 int i; 149 150 va_list ap; 151 va_start(ap, fmt); 152 (void) vsnprintf(p, sizeof p, fmt, ap); 153 va_end(ap); 154 |
155 debug(ftp, "send <%s>\n",p); | 155 debug(ftp, "send <%s>\n", p); |
156 strcat(p,"\r\n"); | 156 strcat(p,"\r\n"); |
157 if (writes(ftp->fd_ctrl,p)) | 157 if (writes(ftp->fd_ctrl, p)) |
158 return -2; | 158 return -2; |
159 i = get_a_number(ftp,0); | 159 i = get_a_number(ftp, 0); |
160 return i; 161} 162 163FTP_t 164FtpInit() 165{ 166 FTP_t ftp; 167 --- 66 unchanged lines hidden (view full) --- 234 (void)close(s); 235 return zap(ftp); 236 } 237 238 ftp->fd_ctrl = s; 239 240 debug(ftp, "open (%d)\n",get_a_number(ftp,0)); 241 | 160 return i; 161} 162 163FTP_t 164FtpInit() 165{ 166 FTP_t ftp; 167 --- 66 unchanged lines hidden (view full) --- 234 (void)close(s); 235 return zap(ftp); 236 } 237 238 ftp->fd_ctrl = s; 239 240 debug(ftp, "open (%d)\n",get_a_number(ftp,0)); 241 |
242 i = cmd(ftp,"USER %s",user); | 242 i = cmd(ftp, "USER %s", user); |
243 if (i >= 300 && i < 400) 244 i = cmd(ftp,"PASS %s",passwd); 245 if (i >= 299 || i < 0) { | 243 if (i >= 300 && i < 400) 244 i = cmd(ftp,"PASS %s",passwd); 245 if (i >= 299 || i < 0) { |
246 close(ftp->fd_ctrl); ftp->fd_ctrl = -1; | 246 close(ftp->fd_ctrl); 247 ftp->fd_ctrl = -1; |
247 return zap(ftp); 248 } 249 ftp->state = isopen; 250 return 0; 251} 252 253void 254FtpClose(FTP_t ftp) --- 7 unchanged lines hidden (view full) --- 262 debug(ftp, "FtpClose(ftp)\n"); 263 zap(ftp); 264} 265 266int 267FtpChdir(FTP_t ftp, char *dir) 268{ 269 int i; | 248 return zap(ftp); 249 } 250 ftp->state = isopen; 251 return 0; 252} 253 254void 255FtpClose(FTP_t ftp) --- 7 unchanged lines hidden (view full) --- 263 debug(ftp, "FtpClose(ftp)\n"); 264 zap(ftp); 265} 266 267int 268FtpChdir(FTP_t ftp, char *dir) 269{ 270 int i; |
271 |
|
270 if (ftp->state != isopen) 271 return botch(ftp,"FtpChdir","open"); | 272 if (ftp->state != isopen) 273 return botch(ftp,"FtpChdir","open"); |
272 i = cmd(ftp,"CWD %s",dir); | 274 i = cmd(ftp, "CWD %s", dir); |
273 if (i < 0) 274 return i; 275 else if (i != 250) 276 return -1; 277 return 0; 278} 279 280int 281FtpGet(FTP_t ftp, char *file) 282{ 283 int i,s; 284 char *q; 285 unsigned char addr[64]; 286 struct sockaddr_in sin; 287 u_long a; 288 | 275 if (i < 0) 276 return i; 277 else if (i != 250) 278 return -1; 279 return 0; 280} 281 282int 283FtpGet(FTP_t ftp, char *file) 284{ 285 int i,s; 286 char *q; 287 unsigned char addr[64]; 288 struct sockaddr_in sin; 289 u_long a; 290 |
289 debug(ftp, "FtpGet(ftp,%s)\n",file); | 291 debug(ftp, "FtpGet(ftp,%s)\n", file); |
290 if (ftp->state != isopen) | 292 if (ftp->state != isopen) |
291 return botch(ftp,"FtpGet","open"); 292 if(ftp->binary) { 293 i = cmd(ftp,"TYPE I"); | 293 return botch(ftp, "FtpGet", "open"); 294 if (ftp->binary) { 295 i = cmd(ftp, "TYPE I"); |
294 if (i < 0 || FTP_TIMEOUT(i)) 295 return zap(ftp); 296 if (i > 299) 297 return -1; | 296 if (i < 0 || FTP_TIMEOUT(i)) 297 return zap(ftp); 298 if (i > 299) 299 return -1; |
298 } else { 299 return -1; | |
300 } | 300 } |
301 else 302 return -1; |
|
301 302 if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) 303 return zap(ftp); 304 305 if (ftp->passive) { | 303 304 if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) 305 return zap(ftp); 306 307 if (ftp->passive) { |
306 debug(ftp, "send <%s>\n","PASV"); 307 if (writes(ftp->fd_ctrl,"PASV\r\n")) | 308 debug(ftp, "send <%s>\n", "PASV"); 309 if (writes(ftp->fd_ctrl, "PASV\r\n")) |
308 return zap(ftp); | 310 return zap(ftp); |
309 i = get_a_number(ftp,&q); | 311 i = get_a_number(ftp, &q); |
310 if (i < 0) 311 return zap(ftp); 312 if (i != 227) 313 return zap(ftp); 314 while (*q && !isdigit(*q)) 315 q++; 316 if (!*q) 317 return zap(ftp); 318 q--; | 312 if (i < 0) 313 return zap(ftp); 314 if (i != 227) 315 return zap(ftp); 316 while (*q && !isdigit(*q)) 317 q++; 318 if (!*q) 319 return zap(ftp); 320 q--; |
319 for(i=0;i<6;i++) { | 321 for(i = 0; i < 6; i++) { |
320 q++; | 322 q++; |
321 addr[i] = strtol(q,&q,10); | 323 addr[i] = strtol(q, &q, 10); |
322 } 323 324 sin.sin_family = ftp->addrtype; 325 bcopy(addr, (char *)&sin.sin_addr, 4); | 324 } 325 326 sin.sin_family = ftp->addrtype; 327 bcopy(addr, (char *)&sin.sin_addr, 4); |
326 bcopy(addr+4, (char *)&sin.sin_port, 2); | 328 bcopy(addr + 4, (char *)&sin.sin_port, 2); |
327 debug(ftp, "Opening active socket to %s : %u\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port)); 328 329 debug(ftp, "Connecting to %s:%u\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port)); 330 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { 331 (void)close(s); 332 debug(ftp, "connect: %s (%d)\n", strerror(errno), errno); 333 return -1; 334 } 335 ftp->fd_xfer = s; | 329 debug(ftp, "Opening active socket to %s : %u\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port)); 330 331 debug(ftp, "Connecting to %s:%u\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port)); 332 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { 333 (void)close(s); 334 debug(ftp, "connect: %s (%d)\n", strerror(errno), errno); 335 return -1; 336 } 337 ftp->fd_xfer = s; |
336 i = cmd(ftp,"RETR %s",file); | 338 i = cmd(ftp,"RETR %s", file); |
337 if (i < 0 || FTP_TIMEOUT(i)) { 338 close(s); 339 return zap(ftp); 340 } 341 else if (i > 299) { 342 if (isDebug()) 343 msgDebug("FTP: No such file %s, moving on.\n", file); 344 close(s); 345 return -1; 346 } 347 ftp->state = xfer; 348 return s; 349 } else { 350 i = sizeof sin; | 339 if (i < 0 || FTP_TIMEOUT(i)) { 340 close(s); 341 return zap(ftp); 342 } 343 else if (i > 299) { 344 if (isDebug()) 345 msgDebug("FTP: No such file %s, moving on.\n", file); 346 close(s); 347 return -1; 348 } 349 ftp->state = xfer; 350 return s; 351 } else { 352 i = sizeof sin; |
351 getsockname(ftp->fd_ctrl,(struct sockaddr *)&sin,&i); | 353 getsockname(ftp->fd_ctrl, (struct sockaddr *)&sin, &i); |
352 sin.sin_port = 0; 353 i = sizeof sin; 354 if (bind(s,(struct sockaddr *)&sin, i) < 0) { | 354 sin.sin_port = 0; 355 i = sizeof sin; 356 if (bind(s,(struct sockaddr *)&sin, i) < 0) { |
355 close (s); 356 debug(ftp,"bind failed %d\n",errno); 357 return zap(ftp); | 357 close (s); 358 debug(ftp, "bind failed %d\n", errno); 359 return zap(ftp); |
358 } | 360 } |
359 getsockname(s,(struct sockaddr *)&sin,&i); 360 if (listen(s,1) < 0) { 361 close (s); 362 debug(ftp,"listen failed %d\n",errno); 363 return zap(ftp); | 361 getsockname(s, (struct sockaddr *)&sin, &i); 362 if (listen(s, 1) < 0) { 363 close (s); 364 debug(ftp, "listen failed %d\n", errno); 365 return zap(ftp); |
364 } 365 a = ntohl(sin.sin_addr.s_addr); | 366 } 367 a = ntohl(sin.sin_addr.s_addr); |
366 i = cmd(ftp,"PORT %d,%d,%d,%d,%d,%d", | 368 i = cmd(ftp, "PORT %d,%d,%d,%d,%d,%d", |
367 (a >> 24) & 0xff, 368 (a >> 16) & 0xff, 369 (a >> 8) & 0xff, | 369 (a >> 24) & 0xff, 370 (a >> 16) & 0xff, 371 (a >> 8) & 0xff, |
370 a & 0xff, | 372 a & 0xff, |
371 (ntohs(sin.sin_port) >> 8) & 0xff, | 373 (ntohs(sin.sin_port) >> 8) & 0xff, |
372 ntohs(sin.sin_port) & 0xff); | 374 ntohs(sin.sin_port) & 0xff); |
373 if (i != 200) 374 return -1; | 375 if (i != 200) 376 return -1; |
375 i = cmd(ftp,"RETR %s",file); | 377 i = cmd(ftp,"RETR %s", file); |
376 if (i < 0) { 377 close(s); 378 return zap(ftp); 379 } 380 else if (i > 299 || FTP_TIMEOUT(i)) { 381 if (isDebug()) 382 msgDebug("FTP: No such file %s, moving on.\n", file); 383 close(s); --- 14 unchanged lines hidden (view full) --- 398} 399 400int 401FtpEOF(FTP_t ftp) 402{ 403 int i; 404 405 if (ftp->state != xfer) | 378 if (i < 0) { 379 close(s); 380 return zap(ftp); 381 } 382 else if (i > 299 || FTP_TIMEOUT(i)) { 383 if (isDebug()) 384 msgDebug("FTP: No such file %s, moving on.\n", file); 385 close(s); --- 14 unchanged lines hidden (view full) --- 400} 401 402int 403FtpEOF(FTP_t ftp) 404{ 405 int i; 406 407 if (ftp->state != xfer) |
406 return botch(ftp,"FtpEOF","xfer"); | 408 return botch(ftp, "FtpEOF", "xfer"); |
407 debug(ftp, "FtpEOF(ftp)\n"); | 409 debug(ftp, "FtpEOF(ftp)\n"); |
408 close(ftp->fd_xfer); ftp->fd_xfer = -1; | 410 close(ftp->fd_xfer); 411 ftp->fd_xfer = -1; |
409 ftp->state = isopen; 410 i = get_a_number(ftp,0); 411 if (i < 0) 412 return zap(ftp); 413 else if (i != 250 && i != 226) 414 return -1; 415 else 416 return 0; --- 30 unchanged lines hidden --- | 412 ftp->state = isopen; 413 i = get_a_number(ftp,0); 414 if (i < 0) 415 return zap(ftp); 416 else if (i != 250 && i != 226) 417 return -1; 418 else 419 return 0; --- 30 unchanged lines hidden --- |