/* * FtpAccess - return a handle for a data stream * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpAccess (const char *path, int typ, int mode, netbuf *nControl, netbuf **nData) { char buf[256]; int dir; if ((path == NULL) && ((typ == FTPLIB_FILE_WRITE) || (typ == FTPLIB_FILE_READ))) { sprintf(nControl->response, "Missing path argument for file transfer\n"); return 0; } sprintf(buf, "TYPE %c", mode); if (!FtpSendCmd(buf, '2', nControl)) return 0; switch (typ) { case FTPLIB_DIR: strcpy(buf, "NLST"); dir = FTPLIB_READ; break; case FTPLIB_DIR_VERBOSE: strcpy(buf, "LIST"); dir = FTPLIB_READ; break; case FTPLIB_FILE_READ: strcpy(buf, "RETR"); dir = FTPLIB_READ; break; case FTPLIB_FILE_WRITE: strcpy(buf, "STOR"); dir = FTPLIB_WRITE; break; default: sprintf(nControl->response, "Invalid open type %d\n", typ); return 0; } if (path != NULL) { int i = strlen(buf); buf[i++] = ' '; if ((strlen(path) + i) >= sizeof (buf)) return 0; strcpy(&buf[i], path); } if (FtpOpenPort(nControl, nData, mode, dir) == -1) return 0; if (!FtpSendCmd(buf, '1', nControl)) { FtpClose(*nData); *nData = NULL; return 0; } (*nData)->ctrl = nControl; nControl->data = *nData; if (nControl->cmode == FTPLIB_PORT) { if (!FtpAcceptConnection(*nData, nControl)) { FtpClose(*nData); *nData = NULL; nControl->data = NULL; return 0; } } return 1; }
/* * FtpClose - close a data connection */ GLOBALDEF int FtpClose(netbuf *nData) { netbuf *ctrl; switch (nData->dir) { case FTPLIB_WRITE: /* potential problem - if buffer flush fails, how to notify user? */ if (nData->buf != NULL) writeline(NULL, 0, nData); case FTPLIB_READ: if (nData->buf) free(nData->buf); shutdown(nData->handle,2); net_close(nData->handle); ctrl = nData->ctrl; free(nData); if (ctrl) { ctrl->data = NULL; return(readresp('2', ctrl)); } return 1; case FTPLIB_CONTROL: if (nData->data) { nData->ctrl = NULL; FtpClose(nData); } net_close(nData->handle); free(nData); return 0; } return 1; }
/* * FtpXfer - issue a command and transfer data * * return 1 if successful, 0 otherwise */ static int FtpXfer(const char *localfile, const char *path, netbuf *nControl, int typ, int mode) { int l,c; char *dbuf; FILE *local = NULL; netbuf *nData; int rv=1; int writeResult = 0; if (localfile != NULL) { char ac[4] = "w"; if (typ == FTPLIB_FILE_WRITE) ac[0] = 'r'; if (mode == FTPLIB_IMAGE) ac[1] = 'b'; local = fopen(localfile, ac); if (local == NULL) { strncpy(nControl->response, strerror(errno), sizeof(nControl->response)); return 0; } } if (local == NULL) local = (typ == FTPLIB_FILE_WRITE) ? stdin : stdout; if (!FtpAccess(path, typ, mode, nControl, &nData)) return 0; dbuf = malloc(FTPLIB_BUFSIZ); if (typ == FTPLIB_FILE_WRITE) { while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0) if ((c = FtpWrite(dbuf, l, nData)) < l) { if (ftplib_debug > 1) printf("short write: passed %d, wrote %d\n", l, c); rv = 0; break; } } else { while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0) { writeResult = (nData->writercb) ? nData->writercb(nData, dbuf, l, nData->writerarg) : fwrite(dbuf, 1, l, local); if (writeResult <= 0) { perror("localstore write"); rv = 0; break; } } } free(dbuf); fflush(local); if (localfile != NULL) fclose(local); FtpClose(nData); return rv; }
STATUS FtpRetr (FTP * con , char * command , char *in , char * out) { FILE *o; struct stat st; char buffer[FTPBUFSIZ]; register int size; FtpFilenameChecker(&in,&out); if ( FtpTestFlag(con,FTP_REST) && stat(out,&st)==0) { con -> seek = st.st_size; if ((o=Ftpfopen(out,"a+"))==NULL) return EXIT(con,LQUIT); } else { con -> seek = 0; if ((o=Ftpfopen(out,"w+"))==NULL) return EXIT(con,LQUIT); } if ( FtpError(FtpData(con,command,in,"r"))) { if (con->seek==0) return EXIT(con,con->err_no); con -> seek = 0; fclose(o); if ( FtpError(FtpData(con,command,in,"r")) ) { return EXIT(con,con->err_no); } if ((o=Ftpfopen(out,"w+"))==NULL) return EXIT(con,LQUIT); } fseek(o,con->seek,0); while((size=FtpReadBlock(con,buffer,FTPBUFSIZ))>0) { if (write(fileno(o),buffer,size)!=size) { Ftpfclose(o); return EXIT(con,LQUIT); } } Ftpfclose(o); return FtpClose(con); }
/* * FtpXfer - issue a command and transfer data * * return 1 if successful, 0 otherwise */ static int FtpXfer(const char *localfile, const char *path, netbuf *nControl, int typ, int mode) { int l,c; char *dbuf; FILE *local = NULL; netbuf *nData; if (localfile != NULL) { local = fopen(localfile, (typ == FTPLIB_FILE_WRITE) ? "r" : "w"); if (local == NULL) { strncpy(nControl->response, strerror(errno), sizeof(nControl->response)); return 0; } } if (local == NULL) local = (typ == FTPLIB_FILE_WRITE) ? stdin : stdout; if (!FtpAccess(path, typ, mode, nControl, &nData)) return 0; dbuf = malloc(FTPLIB_BUFSIZ); if (typ == FTPLIB_FILE_WRITE) { while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0) if ((c = FtpWrite(dbuf, l, nData)) < l) printf("short write: passed %d, wrote %d\n", l, c); } else { while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0) if (fwrite(dbuf, 1, l, local) <= 0) { perror("localfile write"); break; } } free(dbuf); fflush(local); if (localfile != NULL) fclose(local); return FtpClose(nData); }
int main(int argc, char *argv[]) { int files_processed = 0; int opt; invocation = argv[0]; optind = 1; if (strstr(argv[0],"send") != NULL) action = FTP_SEND; else if (strstr(argv[0],"get") != NULL) action = FTP_GET; else if (strstr(argv[0],"dir") != NULL) action = FTP_DIR; else if (strstr(argv[0],"list") != NULL) action = FTP_LIST; else if (strstr(argv[0],"rm") != NULL) action = FTP_RM; if ((action == 0) && (argc > 2)) { if ( argc < 3 ) /* command + site */ { usage(); exit( EX_SYNTAX ); } if (strcmp(argv[1],"send") == 0) action = FTP_SEND; else if (strcmp(argv[1],"get") == 0) action = FTP_GET; else if (strcmp(argv[1],"dir") == 0) action = FTP_DIR; else if (strcmp(argv[1],"list") == 0) action = FTP_LIST; else if (strcmp(argv[1],"rm") == 0) action = FTP_RM; if (action) optind++; } if (action == 0) { usage(); exit(EX_SYNTAX); } FtpInit(); // while (argv[optind] != NULL) while ( optind < argc ) { if (argv[optind][0] != '-') { if (host == NULL) host = argv[optind++]; else { process_file(argv[optind++]); files_processed++; } continue; } opt = getopt(argc,argv,"abil:m:p:r:s:v:w"); switch (opt) { case '?' : fprintf(stderr,"Invalid option: %c\n", opt); usage(); exit(EX_SYNTAX); case ':' : usage(); exit(EX_SYNTAX); case 'a' : mode = 'A'; break; case 'b' : strippath = !strippath; break; case 'i' : mode = 'I'; break; case 'l' : user = optarg; break; case 'm' : set_umask(optarg); break; case 'p' : pass = optarg; break; case 'r' : change_directory(optarg); break; case 's' : site_cmd(optarg); break; case 'v' : if (opt == ':') ftplib_debug++; else ftplib_debug = atoi(optarg); break; case 'w' : wildcard = !wildcard; break; default : usage(); exit(EX_SYNTAX); } } if (files_processed == 0) { ftp_connect(); if ((action == FTP_DIR) || (action == FTP_LIST)) process_file(NULL); else { char fnm[256]; do { char *nl; if (isatty(fileno(stdin))) printf("file> "); if (fgets(fnm, sizeof(fnm), stdin) == NULL) break; if ((nl = strchr(fnm,'\n')) != NULL) *nl = '\0'; process_file(fnm); } while (1); } } if (conn) FtpClose(conn); return 0; }
void process_file(char *fnm) { int sts=0; fsz_t fsz; struct REMFILE *filelist = NULL; struct REMFILE rem; ftp_connect(); FtpClearCallback(conn); if ((action == FTP_SEND) || (action == FTP_GET) || (action == FTP_RM)) { if (action == FTP_SEND) { struct stat info; if (stat(fnm,&info) == -1) { perror(fnm); return; } if (S_ISDIR(info.st_mode)) { if (!FtpMkdir(fnm, conn)) fprintf(stderr,"mkdir %s failed\n%s",fnm,FtpLastResponse(conn)); else if (ftplib_debug) fprintf(stderr,"Directory %s created\n",fnm); return; } fsz = info.st_size; } else { if (!wildcard) { struct REMFILE *f; f = (struct REMFILE *) malloc(sizeof(struct REMFILE)); memset(f,0,sizeof(struct REMFILE)); f->next = filelist; filelist = f; f->fnm = strdup(fnm); } else { netbuf *dir; char *buf; if (!FtpAccess(fnm, FTPLIB_DIR, FTPLIB_ASCII, conn, &dir)) { fprintf(stderr,"error requesting directory of %s\n%s\n", fnm, FtpLastResponse(conn)); return; } buf = malloc(DIRBUF_SIZE); while (FtpRead(buf, DIRBUF_SIZE, dir) > 0) { struct REMFILE *f; char *p; f = (struct REMFILE *) malloc(sizeof(struct REMFILE)); memset(f,0,sizeof(struct REMFILE)); f->next = filelist; p = strchr(buf,'\n'); if (p) *p = '\0'; f->fnm = strdup(buf); filelist = f; } free(buf); FtpClose(dir); } } } switch (action) { case FTP_DIR : sts = FtpDir(NULL, fnm, conn); break; case FTP_LIST : sts = FtpNlst(NULL, fnm, conn); break; case FTP_SEND : rem.next = NULL; rem.fnm = fnm; rem.fsz = fsz; fsz /= 100; if (fsz > 100000) fsz = 100000; if (ftplib_debug && fsz) { FtpCallbackOptions opt; opt.cbFunc = log_progress; opt.cbArg = &rem; opt.idleTime = 1000; opt.bytesXferred = fsz; FtpSetCallback(&opt,conn); } sts = FtpPut(fnm,strippath ? basename(fnm) : fnm,mode,conn); if (ftplib_debug && sts) printf("%s sent\n",fnm); break; case FTP_GET : while (filelist) { struct REMFILE *f = filelist; filelist = f->next; #if defined(__UINT64_MAX) if (!FtpSizeLong(f->fnm, &fsz, mode, conn)) #else if (!FtpSize(f->fnm, &fsz, mode, conn)) #endif fsz = 0; f->fsz = fsz; fsz /= 100; if (fsz > 100000) fsz = 100000; if ( fsz == 0 ) fsz = 32768; if (ftplib_debug) { FtpCallbackOptions opt; opt.cbFunc = log_progress; opt.cbArg = f; opt.idleTime = 1000; opt.bytesXferred = fsz; FtpSetCallback(&opt,conn); } sts = FtpGet(f->fnm,f->fnm,mode,conn); if (ftplib_debug && sts) printf("%s retrieved\n",f->fnm); free(f->fnm); free(f); } break; case FTP_RM : while (filelist) { struct REMFILE *f = filelist; filelist = f->next; sts = FtpDelete(f->fnm,conn); if (ftplib_debug && sts) printf("%s deleted\n", f->fnm); free(f->fnm); free(f); } break; } if (!sts) printf("ftp error\n%s\n",FtpLastResponse(conn)); return; }
long FtpFileDownload( void *fs, char *url, char *dest, char *fullpath, long length ) { long dataread, datatotal=0; if ( fs ) { void *fp; FILE *ff; char *buffer=NULL; if ( fs && !IsStopped() ) { if ( !(ff = fopen( dest, "wb+" )) ) { StatusSetf( "Cannot open local file %s for writing.", dest ); return -2; } fp = (void*)FtpOpen( fs, fullpath, 'R' ); if ( fp ) { if ( !length ) length = FtpFileGetSize( url ); StatusSetID( IDS_DOWNLOADING, fullpath ); buffer = (char*)malloc( 1024*4 ); if ( length && buffer ) { long writesize; dataread = 1; while( dataread>0 && buffer && !IsStopped() ) { //sprintf( msg, "Downloading %s...%d KB (%.2f%%)", fullpath, (datatotal)/1024, (100*((datatotal)/(float)length)) ); StatusSetID( IDS_DOWNLOADINGKB, fullpath, (datatotal)/1024, (100*((datatotal)/(float)length)) ); dataread = NetRead( fp, buffer, 1024*1 ); datatotal+= dataread; if ( dataread ){ writesize = fwrite( buffer, 1, dataread, ff ); if ( writesize == 0 ){ dataread = 0; datatotal = -2; } } } free( buffer ); } FtpClose( fp ); } else { const char *msg = NetworkErr( NULL ); if ( !msg ) msg = "Maybe path does not exist?"; ErrorMsg( "Cannot open ftp file %s\nbecause ...\n%s", fullpath, msg ); datatotal = -1; } fclose( ff ); } if ( IsStopped() ) { StatusSetID( IDS_DOWNLOADSTOP ); remove( dest ); datatotal = -1; } } return datatotal; }
int PostProc_UploadLogs( char *uploadloglocation, int deletelog, int compressed_logs, char **files , long fileCount ) { char newfilename[256]; char sourcepath[256]; if ( files && fileCount ) { char *source, *p; long count=0, filenum, perc, doftp=FALSE, ret; LLStructRecPtr next = gFopenHistoryPtr; char server[128]; char ftppath[256], file[128]; char name[64]; char passwd[32]; char msg[256]; void *fs; if ( IsURL( uploadloglocation ) ) { ExtractUserFromURL( uploadloglocation, server, name, passwd, ftppath ); fs = (void*)FtpServerOpen( server, name, passwd ); if ( fs ){ doftp = TRUE; sprintf( msg, "FTP: %s@%s/%s", name,server,ftppath ); StatusSet( msg ); } else { FtpServerOpenError( server ); return 1; } } else StatusSetID( IDS_COPYINGFILE, "." ); // upload log files..... if ( fs ) { count = 0; filenum = fileCount; // go through all logs..... while( files[count] && !IsStopped() ) { perc = ((100*count)/filenum); StatusWindowSetProgress( perc, NULL ); PathFromFullPath( files[count], sourcepath ); source = files[count]; if ( strstr( source, sourcepath ) ) { source += strlen( sourcepath ); } // Upload LOGS if ( doftp ) { long upstatus; p = files[count] + strlen( sourcepath ); if ( compressed_logs && !strstr( p, ".gz" ) ) sprintf( file, "%s%s.gz", ftppath, p ); else sprintf( file, "%s%s", ftppath, p ); upstatus = FtpFileUpload( fs, files[count], file, p ); if ( upstatus == FTPERR_COMPLETE ) { if( deletelog ) ret = remove( files[count] ); } } else { CopyFilenameUsingPath( newfilename, uploadloglocation, source ); } count++; } } if ( doftp ) FtpClose( fs ); } else return 2; return 0; }
int PostProc_UploadReport( const char *uploadURL, int deletereport, int zipreport, char *reportLocation ) { if ( gFopenHistoryPtr && !IsStopped() ) { char sourcepath[256]; char server[256], ftppath[256], name[64], passwd[32]; char *source; void *fs; if ( IsURL( uploadURL ) ) { char msg[256]; ExtractUserFromURL( (char*)uploadURL, server, name, passwd, ftppath ); DateFixFilename( ftppath, 0 ); fs = (void*)FtpServerOpen( server, name, passwd ); if ( fs ){ sprintf( msg, "FTP %s@%s/%s", name,server,ftppath ); StatusSet( msg ); } else { FtpServerOpenError( server ); return 1; } } PathFromFullPath( reportLocation, sourcepath ); DateFixFilename( sourcepath, 0 ); // ---------------- UPLOAD ALL INDIVIDUAL FILES if ( !zipreport ) { long files; files = UploadFiles( fs, (char*)uploadURL, sourcepath, ftppath, deletereport ); if ( files>0 ) OutDebugs( "%d files uploaded.", files ); else OutDebugs( "Upload canceled" ); FtpClose( fs ); OutDebugs( "Ftp Site Closed" ); } else // ----------------- UPLOAD SINGLE ZIP REPORT { long uploadStatus = 0; char srczipname[256]; char newfilename[256]; mystrcpy( srczipname, reportLocation ); DateFixFilename( srczipname, 0 ); PathFromFullPath( srczipname, sourcepath ); if ( !strstr( srczipname, ".zip" ) ) { source = strrchr( srczipname, '.' ); if ( source ) mystrcpy( source, ".zip" ); else return 3; } source = srczipname; // Find the FILENAME Component if ( strstr( srczipname, sourcepath ) ) { source += strlen( sourcepath ); } // generate remote full path PATH+NAME CopyFilenameUsingPath( newfilename, (char*)uploadURL, source ); // Ok things are ok, lets now upload the zip file if ( IsURL( uploadURL ) ) { char fullURLPath[256]; sprintf( fullURLPath, "%s%s", ftppath, source ); // upload the zip file uploadStatus = FtpFileUpload( fs, srczipname, fullURLPath, source ); if ( uploadStatus == FTPERR_CANTMAKEDIR ) ErrorMsg( "Could not make directory %s on ftp server .\nMaybe path does not exist?", ftppath ); FtpClose( fs ); } if( deletereport && uploadStatus == FTPERR_COMPLETE ) { OutDebugs( "Deleting local zip file %s", srczipname ); remove( srczipname ); } } } return 0; }
// -2 cant make dir long FtpFileUpload( void *fs, char *localfilename, char *remotepath, char *file ) { long length=0, failedmkdir=FALSE, datadone; if ( fs && !IsStopped() ) { void *hFtpFile; FILE *ff; long dataleft, dataread, perc; char *buffer=NULL; char msg[500]; if ( !(ff = fopen( localfilename, "rb" )) ) { StatusSetID( IDS_ERR_FILEFAILED, localfilename ); return FTPERR_NOFILE; } if ( fs && ff ) { char dir[256], *p; static char lastdir[256]; int tries = 0; // Convert all Windows slashes to Unix ones. p = remotepath; while( *p ) { if ( *p == '\\' ) *p = '/'; p++; } // Try to create the remote directories first. if ( p ) { // Try to open remote file, if we cant make the remote dir. while( (hFtpFile = (void*)FtpOpen( fs, remotepath, 'W' )) == NULL && tries<5 ) { PathFromFullPath( remotepath, dir ); if ( strcmp( dir, lastdir ) ){ //long l=mystrcpy( lastdir, dir ); //if ( dir[l-1] == '/' ) dir[l-1]=0; sprintf( msg, "Making dir %s...", dir ); StatusSet( msg ); if ( !FtpMakeDir( fs, dir ) ) { failedmkdir = TRUE; OutDebugs( "Cannot create remote ftp directory %s", dir ); } else { failedmkdir = FALSE; } } tries++; OutDebug( "Trying again to write to server..." ); } } // If remote file is opened. if ( hFtpFile ) { StatusSetID( IDS_UPLOADINGTO, remotepath ); const long read_size = (4*1024); datadone = 0; length = dataleft = (long)GetFileLength( localfilename ); if ( length ) buffer = (char*)malloc( read_size ); if ( buffer ) { while( dataleft>0 && buffer && !IsStopped() ) { dataread = fread( buffer, 1, read_size, ff ); if ( dataread ) NetWrite( hFtpFile, buffer, dataread ); dataleft -= dataread; datadone += dataread; // ------------------------------------------------------ perc = (long)(100*((length-dataleft)/(float)length)); sprintf( msg, "Uploading %s (%d bytes %d%%)", remotepath, datadone, perc ); StatusSet( msg ); // ------------------------------------------------------ } if ( datadone == length ) OutDebug( "Uploaded complete." ); free( buffer ); } FtpClose( hFtpFile ); OutDebug( "Ftp File Closed" ); } } if ( ff ) fclose( ff ); } if ( failedmkdir ) return FTPERR_CANTMAKEDIR; if ( IsStopped() ) return FTPERR_STOPPED; if ( datadone == length ) return FTPERR_COMPLETE; return FTPERR_COMPLETEFAIL; }
void process_file(char *fnm) { int sts = 0; int fsz; struct REMFILE *filelist = NULL; struct REMFILE rem; ftp_connect(); FtpOptions(FTPLIB_CALLBACK, (long) NULL, conn); if ((action == FTP_SEND) || (action == FTP_GET)) { if (action == FTP_SEND) { struct stat info; if (stat(fnm, &info) == -1) { perror(fnm); return; } if (S_ISDIR(info.st_mode)) { if (!ftpMkdir(fnm)) fprintf(stderr, "mkdir %s failed\n%s", fnm, FtpLastResponse(conn)); else if (ftplib_debug) fprintf(stderr, "Directory %s created\n", fnm); return; } fsz = info.st_size; } else { if (!wildcard) { struct REMFILE *f; f = (struct REMFILE *) malloc(sizeof(struct REMFILE)); memset(f, 0, sizeof(struct REMFILE)); f->next = filelist; filelist = f; f->fnm = strdup(fnm); } else { netbuf * dir; char *buf; if (!FtpAccess(fnm, FTPLIB_DIR, FTPLIB_ASCII, conn, &dir)) { fprintf(stderr, "error requesting directory of %s\n%s\n", fnm, FtpLastResponse(conn)); return; } buf = malloc(DIRBUF_SIZE); while (FtpRead(buf, DIRBUF_SIZE, dir) > 0) { struct REMFILE *f; char *p; f = (struct REMFILE *) malloc(sizeof(struct REMFILE)); memset(f, 0, sizeof(struct REMFILE)); f->next = filelist; p = strchr(buf, '\n'); if (p) *p = '\0'; f->fnm = strdup(buf); filelist = f; } free(buf); FtpClose(dir); } } } switch (action) { case FTP_DIR: sts = FtpDir(NULL, fnm, conn); break; case FTP_LIST: sts = FtpNlst(NULL, fnm, conn); break; case FTP_SEND: rem.next = NULL; rem.fnm = fnm; rem.fsz = fsz; fsz /= 10; if (fsz > 100000) fsz = 100000; if (ftplib_debug && fsz) { FtpOptions(FTPLIB_CALLBACK, (long) log_progress, conn); FtpOptions(FTPLIB_IDLETIME, (long) 1000, conn); FtpOptions(FTPLIB_CALLBACKARG, (long) &rem, conn); FtpOptions(FTPLIB_CALLBACKBYTES, (long) fsz, conn); } sts = FtpPut(fnm, fnm, mode, conn); if (ftplib_debug && sts) printf("%s sent\n", fnm); break; case FTP_GET: while (filelist) { struct REMFILE *f = filelist; filelist = f->next; if (!FtpSize(f->fnm, &fsz, mode, conn)) fsz = 0; f->fsz = fsz; fsz /= 10; if (fsz > 100000) fsz = 100000; if (ftplib_debug && fsz) { FtpOptions(FTPLIB_CALLBACK, (long) log_progress, conn); FtpOptions(FTPLIB_IDLETIME, (long) 1000, conn); FtpOptions(FTPLIB_CALLBACKARG, (long) f, conn); FtpOptions(FTPLIB_CALLBACKBYTES, (long) fsz, conn); } sts = FtpGet(f->fnm, f->fnm, mode, conn); if (ftplib_debug && sts) printf("%s retrieved\n", f->fnm); free(f->fnm); free(f); } break; case FTP_RM: while (filelist) { struct REMFILE *f = filelist; filelist = f->next; sts = FtpDelete(f->fnm, conn); if (ftplib_debug && sts) printf("%s deleted\n", f->fnm); free(f->fnm); free(f); } break; } if (!sts) printf("ftp error\n%s\n", FtpLastResponse(conn)); return; }