|
|
1.1 ! root 1: /* ftp_lib.c - FTP subroutines */ ! 2: ! 3: /* ! 4: * $Header: /f/osi/ftam-ftp/RCS/ftp_lib.c,v 7.0 89/11/23 21:55:06 mrose Rel $ ! 5: * ! 6: * ! 7: * $Log: ftp_lib.c,v $ ! 8: * Revision 7.0 89/11/23 21:55:06 mrose ! 9: * Release 6.0 ! 10: * ! 11: */ ! 12: ! 13: /* ! 14: * NOTICE ! 15: * ! 16: * The MITRE Corporation (hereafter MITRE) makes this software available ! 17: * on an "as is" basis. No guarantees, either explicit or implied, are ! 18: * given as to performance or suitability. ! 19: * ! 20: */ ! 21: ! 22: /* ! 23: * Library interface routines. Design of routines is specific for ! 24: * FTAM. ! 25: */ ! 26: ! 27: /* ! 28: * FTP User Program -- Command Routines. ! 29: */ ! 30: #include "config.h" ! 31: #include <sys/param.h> ! 32: #include <sys/stat.h> ! 33: #include <sys/socket.h> ! 34: ! 35: #include <arpa/ftp.h> ! 36: ! 37: #include <signal.h> ! 38: #include <stdio.h> ! 39: #include <errno.h> ! 40: #include <netdb.h> ! 41: ! 42: #include "ftp_var.h" ! 43: #include "general.h" ! 44: #include "logger.h" ! 45: void advise (); ! 46: #define NULLCP ((char *) 0) ! 47: ! 48: #define FTP_PORT 21 ! 49: ! 50: /* Virtual filesystem file types */ ! 51: ! 52: #define VFS_UBF 0 /* offset to FTAM-3 */ ! 53: #define VFS_UTF 1 /* .. FTAM-1 */ ! 54: #define VFS_FDF 2 /* .. NBS-9 */ ! 55: ! 56: #ifndef NOTOK ! 57: #define NOTOK (-1) ! 58: #define OK 0 ! 59: #define DONE 1 ! 60: #endif /* NOTOK */ ! 61: ! 62: ! 63: /* ! 64: * ftp_login: establish command connection with remote host ! 65: * then execute login process. ! 66: */ ! 67: int ! 68: ftp_login(host,user,passwd,acct) ! 69: char *host, *user, *passwd, *acct; ! 70: { ! 71: ! 72: if (connected) return NOTOK; /* already connected */ ! 73: ! 74: ftp_init(); /* initialize control state structures */ ! 75: if (hookup(host,FTP_PORT) == NOTOK) return NOTOK; ! 76: ! 77: ! 78: /* execute login process */ ! 79: if (login(user,passwd,acct) == NOTOK) return NOTOK; ! 80: ! 81: return OK; ! 82: } ! 83: ! 84: /* ! 85: * ftp_quit: send quit command and shutdown communications link. ! 86: */ ! 87: int ! 88: ftp_quit() ! 89: { ! 90: ! 91: extern FILE *cout; ! 92: extern int data; ! 93: int n; ! 94: ! 95: if (!connected) return OK; ! 96: n = command("QUIT"); ! 97: (void) fclose(cout); ! 98: connected = 0; ! 99: data = -1; ! 100: ! 101: if (n == 0 || n == COMPLETE) return OK; ! 102: return NOTOK; ! 103: } ! 104: ! 105: /* ! 106: * ftp_abort: send abort command ! 107: */ ! 108: int ! 109: ftp_abort() ! 110: { ! 111: int n; ! 112: ! 113: if (!connected) return NOTOK; ! 114: n = command("ABOR"); ! 115: ! 116: if (n == COMPLETE) return OK; ! 117: return NOTOK; ! 118: ! 119: } ! 120: ! 121: /* ! 122: * ftp_exist: perform NLST command and count number of records in data ! 123: * stream. If 0 or reply code is failure, file does not exist. If 1 ! 124: * or more and reply code is COMPLETE, file exists. ftp_directory is ! 125: * a global flag. It is set if more than 1 record in data stream and ! 126: * reply code is COMPLETE. Yes this is hokey but it works for all the ! 127: * test systems and is faster than trying a case sensitive, then case ! 128: * insensitive scan then falling back on record counts in the case of ! 129: * directories. ! 130: */ ! 131: int ! 132: ftp_exist(filename) ! 133: char *filename; ! 134: { ! 135: int n, count; ! 136: int fd; ! 137: FILE *fp, *fdopen(); ! 138: char lineX[BUFSIZ]; ! 139: ! 140: ftp_directory = 0; ! 141: ! 142: if (!connected) return NOTOK; ! 143: ! 144: /* set ascii transfer */ ! 145: if (ftp_type(VFS_FDF) != OK) return NOTOK; ! 146: ! 147: /* begin list transfer */ ! 148: if ((fd = recvrequest("NLST",filename)) == NOTOK) return NOTOK; ! 149: if ((fp = fdopen(fd,"r")) == NULL){ ! 150: (void)close(fd); ! 151: (void) getreply(0); ! 152: (void)sprintf(ftp_error,"Out of memory"); ! 153: return NOTOK; ! 154: } ! 155: ! 156: /* count number of records (lines) in data transfer */ ! 157: for(count=0; fgets(lineX,BUFSIZ,fp)!=NULL; count++); ! 158: (void)fclose(fp); ! 159: ! 160: /* transfer complete reply */ ! 161: n = getreply(0); ! 162: ! 163: if (n != COMPLETE) /* directory command not accepted */ ! 164: return NOTOK; ! 165: ! 166: /* if more than one record in reply, guess that it is a directory */ ! 167: if (count > 1) { ! 168: ftp_directory = 1; ! 169: if (verbose) ! 170: advise (LLOG_DEBUG, NULLCP, "directory found"); ! 171: } ! 172: ! 173: /* if any records in reply, assume that file existed */ ! 174: if (count) return OK; ! 175: ! 176: return NOTOK; ! 177: ! 178: } ! 179: ! 180: /* Basicly set transfer type to ascii and issue NLST command ! 181: * and returning the socket descriptor for the data stream. ! 182: */ ! 183: int ! 184: ftp_ls(dir) ! 185: char *dir; ! 186: { ! 187: int fd; ! 188: ! 189: if (!connected) return NOTOK; ! 190: ! 191: /* set ascii transfer */ ! 192: if (ftp_type(VFS_FDF) != OK) return NOTOK; ! 193: ! 194: /* begin list transfer */ ! 195: if ((fd = recvrequest("NLST",dir)) == NOTOK) return NOTOK; ! 196: ! 197: return(fd); ! 198: } ! 199: int ! 200: ftp_delete(file) ! 201: char *file; ! 202: { ! 203: ! 204: ! 205: if (!connected) return NOTOK; ! 206: ! 207: /* send delete command, return OK if complete, NOTOK otherwise */ ! 208: if (command("DELE %s", file) == COMPLETE) return OK; ! 209: /* Hummm, try directory delete */ ! 210: if (command("XRMD %s", file) == COMPLETE) return OK; ! 211: /* No dice, return error */ ! 212: return NOTOK; ! 213: ! 214: } ! 215: ! 216: int ! 217: ftp_mkdir(dir) ! 218: char *dir; ! 219: { ! 220: ! 221: if (!connected) return NOTOK; ! 222: ! 223: /* send MKDIR command, return OK if complete, NOTOK otherwise */ ! 224: if (command("XMKD %s", dir) == COMPLETE) return OK; ! 225: return NOTOK; ! 226: ! 227: } ! 228: ! 229: int ! 230: ftp_rename(from,to) ! 231: char *from, *to; ! 232: { ! 233: int n; ! 234: ! 235: if (!connected) return NOTOK; ! 236: ! 237: /* send RNFR command followed by RNTO if successful */ ! 238: if ((n = command("RNFR %s",from)) == CONTINUE) ! 239: n = command("RNTO %s",to); ! 240: if (n == COMPLETE) return OK; ! 241: return NOTOK; ! 242: ! 243: } ! 244: ! 245: int ! 246: ftp_write(file) ! 247: char *file; ! 248: { ! 249: ! 250: if (!connected) return NOTOK; ! 251: ! 252: return(sendrequest("STOR",file)); ! 253: } ! 254: int ! 255: ftp_append(file) ! 256: char *file; ! 257: { ! 258: if (!connected) return NOTOK; ! 259: ! 260: return(sendrequest("APPE",file)); ! 261: } ! 262: ! 263: int ! 264: ftp_read(file) ! 265: char *file; ! 266: { ! 267: ! 268: if (!connected) return NOTOK; ! 269: ! 270: return(recvrequest("RETR", file)); ! 271: } ! 272: ! 273: int ! 274: ftp_type(modeX) ! 275: int modeX; ! 276: { ! 277: int n; ! 278: char cmd[10]; ! 279: ! 280: /* The current transfer type is stored in ``type''. ! 281: * The TYPE command is issued if the type changes. ! 282: * (this cuts down on the number of FTP transactions). ! 283: */ ! 284: if (!connected) return NOTOK; ! 285: n = COMPLETE; ! 286: ! 287: switch(modeX) { ! 288: /* unstructured binary file */ ! 289: case VFS_UBF: ! 290: if (type == TYPE_L) break; ! 291: (void)sprintf(cmd, "TYPE L %s", bytename); ! 292: type = TYPE_L; ! 293: n = command(cmd,0); ! 294: break; ! 295: /* unstructured text file */ ! 296: case VFS_UTF: ! 297: /* directory file */ ! 298: case VFS_FDF: ! 299: default: ! 300: if (type == TYPE_A) break; ! 301: (void)sprintf(cmd, "TYPE A"); ! 302: type = TYPE_A; ! 303: n = command(cmd,0); ! 304: } ! 305: ! 306: if (n == COMPLETE) return OK; ! 307: return NOTOK; ! 308: ! 309: } ! 310: ! 311: int ! 312: ftp_reply() ! 313: { ! 314: int n; ! 315: ! 316: /* process an FTP response */ ! 317: ! 318: n = getreply(0); ! 319: if (n == COMPLETE) return OK; ! 320: return NOTOK; ! 321: } ! 322: ! 323: int ! 324: ftp_create(filename) ! 325: char *filename; ! 326: { ! 327: int fd,n; ! 328: ! 329: if (!connected) return NOTOK; ! 330: ! 331: /* open file */ ! 332: fd = sendrequest("STOR",filename); ! 333: if (fd == NOTOK) return NOTOK; ! 334: ! 335: /* close file (create empty file) */ ! 336: (void)close(fd); ! 337: n = getreply(0); ! 338: if (n == COMPLETE) return OK; ! 339: return NOTOK; ! 340: ! 341: } ! 342:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.