bool wxCurlFTPTool::GetFTPFs(wxArrayFTPFs& fs, const wxString& szRemoteLoc /*= wxEmptyString*/) { if(List(szRemoteLoc)) { wxString str = wxCURL_BUF2STRING(m_szResponseBody); wxStringInputStream inStream(str); if(inStream.IsOk()) { wxTextInputStream txtInStream(inStream); wxString szCurrentLine = txtInStream.ReadLine(); while(!szCurrentLine.IsEmpty()) { struct ftpparse ftppItem; wxCharBuffer charBuffer(szCurrentLine.ToUTF8()); if(ftpparse(&ftppItem,charBuffer.data(), charBuffer.length()) != 0) { fs.Add(wxCurlFTPFs((wxChar*)ftppItem.name, (ftppItem.flagtrycwd == 1),(ftppItem.flagtryretr == 1), ftppItem.mtime,ftppItem.size)); } szCurrentLine = txtInStream.ReadLine(); } return true; } } return false; }
bool wxCurlFTPTool::GetFTPFs(wxArrayFTPFs& fs, const wxString& szRemoteLoc /*= wxEmptyString*/) { if(List(szRemoteLoc)) { wxString str = wxCURL_BUF2STRING(m_szResponseBody); wxStringInputStream inStream(str); if(inStream.IsOk()) { wxTextInputStream txtInStream(inStream); for(;;) { wxString szCurrentLine = txtInStream.ReadLine(); if(szCurrentLine.empty()) break; wxCharBuffer buf(szCurrentLine.mb_str()); struct ftpparse ftppItem; if(ftpparse(&ftppItem, buf.data(), strlen(buf)) != 0) { fs.Add(wxCurlFTPFs(wxString(ftppItem.name, wxConvLibc), (ftppItem.flagtrycwd == 1),(ftppItem.flagtryretr == 1), ftppItem.mtime,ftppItem.size)); } } return true; } } return false; }
PyObject * ftpparse_wrap(PyObject * self, PyObject * args) { char * buffer; if(! PyArg_ParseTuple(args,"s",&buffer)) return NULL; strcpy(_buffer,buffer); struct ftpparse ret; if(ftpparse(&ret, _buffer, strlen(_buffer)) == 0) return NULL; return Py_BuildValue("(s#iiililis#)", ret.name, ret.namelen, //s# ret.flagtrycwd, //i ret.flagtryretr, //i ret.sizetype, //i ret.size, //l ret.mtimetype, //i ret.mtime, //l = time_t ret.idtype, //i ret.id, ret.idlen //s# ); }
void ftpEntry::listALParse( string entry ) { struct ftpparse *parse = new struct ftpparse(); if( ftpparse( parse, (char*) entry.c_str() , entry.size() ) == 1 ) { _entryDirectory = parse->flagtrycwd; // Size of entry stringstream tmp; tmp << parse->size; _entrySize = tmp.str(); // Number of entrys in folder tmp.str(""); tmp << parse->entrys; _entryCount = tmp.str(); _entryName.append( parse->name, parse->namelen ); tmp.str(""); tmp << parse->mtime; _entryModified = tmp.str(); if( entry[0] == 'l' ) _entryLink = true; } else { string error = "FTP Parse failed on line, "; error.append( entry ); if(_ftpScanner) _ftpScanner->errorSet( error ); _done = true; } delete parse; }
/*################## get_remote_file_names_ftp_list() ###################*/ int get_remote_file_names_ftp_list(off_t *file_size_to_retrieve, int *more_files_in_list) { int files_to_retrieve = 0, i = 0; *file_size_to_retrieve = 0; #ifdef DO_NOT_PARALLELIZE_ALL_FETCH if ((*more_files_in_list == YES) || (db.special_flag & DISTRIBUTED_HELPER_JOB) || ((db.special_flag & OLD_ERROR_JOB) && (db.retries < 30) && (fra[db.fra_pos].stupid_mode != YES) && (fra[db.fra_pos].remove != YES))) #else if (rl_fd == -1) { try_attach_again: if (attach_ls_data(db.fra_pos, db.fsa_pos, db.special_flag, YES) == INCORRECT) { (void)ftp_quit(); exit(INCORRECT); } if ((db.special_flag & DISTRIBUTED_HELPER_JOB) && ((fra[db.fra_pos].stupid_mode == YES) || (fra[db.fra_pos].remove == YES))) { # ifdef LOCK_DEBUG if (rlock_region(rl_fd, LOCK_RETR_PROC, __FILE__, __LINE__) == LOCK_IS_SET) # else if (rlock_region(rl_fd, LOCK_RETR_PROC) == LOCK_IS_SET) # endif { if (i == 0) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Hmm, lock is set. Assume ls_data file was just modified. Lets try it again. (job_no=%d fsa_pos=%d)", (int)db.job_no, db.fsa_pos); } else { if (i == 30) { trans_log(DEBUG_SIGN, __FILE__, __LINE__, NULL, NULL, "Have waited %d seconds, but unable to get a lock. Terminating.", (i * 100000) / 1000000); (void)ftp_quit(); exit(SUCCESS); } my_usleep(100000L); } detach_ls_data(NO); i++; goto try_attach_again; } } } if ((*more_files_in_list == YES) || (db.special_flag & DISTRIBUTED_HELPER_JOB) || ((db.special_flag & OLD_ERROR_JOB) && (db.retries < 30))) #endif { #ifdef DO_NOT_PARALLELIZE_ALL_FETCH if (rl_fd == -1) { if (attach_ls_data(db.fra_pos, db.fsa_pos, db.special_flag, YES) == INCORRECT) { (void)ftp_quit(); exit(INCORRECT); } } #endif *more_files_in_list = NO; for (i = 0; i < no_of_listed_files; i++) { if ((rl[i].retrieved == NO) && (rl[i].assigned == 0)) { #ifdef DO_NOT_PARALLELIZE_ALL_FETCH if ((fra[db.fra_pos].stupid_mode == YES) || (fra[db.fra_pos].remove == YES) || ((files_to_retrieve < fra[db.fra_pos].max_copied_files) && (*file_size_to_retrieve < fra[db.fra_pos].max_copied_file_size))) #else if ((files_to_retrieve < fra[db.fra_pos].max_copied_files) && (*file_size_to_retrieve < fra[db.fra_pos].max_copied_file_size)) #endif { /* Lock this file in list. */ #ifdef LOCK_DEBUG if (lock_region(rl_fd, (off_t)(LOCK_RETR_FILE + i), __FILE__, __LINE__) == LOCK_IS_NOT_SET) #else if (lock_region(rl_fd, (off_t)(LOCK_RETR_FILE + i)) == LOCK_IS_NOT_SET) #endif { if ((fra[db.fra_pos].ignore_size == -1) || ((fra[db.fra_pos].gt_lt_sign & ISIZE_EQUAL) && (fra[db.fra_pos].ignore_size == rl[i].size)) || ((fra[db.fra_pos].gt_lt_sign & ISIZE_LESS_THEN) && (fra[db.fra_pos].ignore_size < rl[i].size)) || ((fra[db.fra_pos].gt_lt_sign & ISIZE_GREATER_THEN) && (fra[db.fra_pos].ignore_size > rl[i].size))) { if ((rl[i].got_date == NO) || (fra[db.fra_pos].ignore_file_time == 0)) { files_to_retrieve++; if ((fra[db.fra_pos].stupid_mode == APPEND_ONLY) && (rl[i].size > rl[i].prev_size)) { *file_size_to_retrieve += (rl[i].size - rl[i].prev_size); } else { *file_size_to_retrieve += rl[i].size; } rl[i].assigned = (unsigned char)db.job_no + 1; } else { time_t diff_time; diff_time = current_time - rl[i].file_mtime; if (((fra[db.fra_pos].gt_lt_sign & IFTIME_EQUAL) && (fra[db.fra_pos].ignore_file_time == diff_time)) || ((fra[db.fra_pos].gt_lt_sign & IFTIME_LESS_THEN) && (fra[db.fra_pos].ignore_file_time < diff_time)) || ((fra[db.fra_pos].gt_lt_sign & IFTIME_GREATER_THEN) && (fra[db.fra_pos].ignore_file_time > diff_time))) { files_to_retrieve++; if ((fra[db.fra_pos].stupid_mode == APPEND_ONLY) && (rl[i].size > rl[i].prev_size)) { *file_size_to_retrieve += (rl[i].size - rl[i].prev_size); } else { *file_size_to_retrieve += rl[i].size; } rl[i].assigned = (unsigned char)db.job_no + 1; } } #ifdef DEBUG_ASSIGNMENT trans_log(DEBUG_SIGN, __FILE__, __LINE__, NULL, NULL, # if SIZEOF_OFF_T == 4 "%s assigned %d: file_name=%s assigned=%d size=%ld", # else "%s assigned %d: file_name=%s assigned=%d size=%lld", # endif (fra[db.fra_pos].ls_data_alias[0] == '\0') ? fra[db.fra_pos].dir_alias : fra[db.fra_pos].ls_data_alias, i, rl[i].file_name, (int)rl[i].assigned, (pri_off_t)rl[i].size); #endif /* DEBUG_ASSIGNMENT */ } #ifdef LOCK_DEBUG unlock_region(rl_fd, (off_t)(LOCK_RETR_FILE + i), __FILE__, __LINE__); #else unlock_region(rl_fd, (off_t)(LOCK_RETR_FILE + i)); #endif } } else { *more_files_in_list = YES; break; } } } } else { unsigned int files_deleted = 0, list_length = 0; int gotcha, j, k, nfg, /* Number of file mask. */ status, type; char file_name[MAX_FILENAME_LENGTH + 1], *list = NULL, *p_end, *p_mask, *p_start; time_t file_mtime; off_t file_size, file_size_deleted = 0, list_size = 0; struct ftpparse fp; struct file_mask *fml = NULL; struct tm *p_tm; /* * Get a directory listing from the remote site so we can see * what files are there. */ #ifdef WITH_SSL if (db.auth == BOTH) { type = LIST_CMD | BUFFERED_LIST | ENCRYPT_DATA; } else { #endif type = LIST_CMD | BUFFERED_LIST; #ifdef WITH_SSL } #endif if ((status = ftp_list(db.mode_flag, type, &list)) != SUCCESS) { trans_log(ERROR_SIGN, __FILE__, __LINE__, NULL, msg_str, "Failed to send LIST command (%d).", status); (void)ftp_quit(); exit(LIST_ERROR); } if (list != NULL) { /* Get all file masks for this directory. */ if ((j = read_file_mask(fra[db.fra_pos].dir_alias, &nfg, &fml)) == INCORRECT) { if (j == LOCKFILE_NOT_THERE) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to set lock in file masks for %s, because the file is not there.", fra[db.fra_pos].dir_alias); } else if (j == LOCK_IS_SET) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to get the file masks for %s, because lock is already set", fra[db.fra_pos].dir_alias); } else { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to get the file masks for %s. (%d)", fra[db.fra_pos].dir_alias, j); } if (fml != NULL) { free(fml); } (void)ftp_quit(); exit(INCORRECT); } #ifdef DO_NOT_PARALLELIZE_ALL_FETCH if ((fra[db.fra_pos].stupid_mode == YES) || (fra[db.fra_pos].remove == YES)) { if (reset_ls_data(db.fra_pos) == INCORRECT) { (void)ftp_quit(); exit(INCORRECT); } } else { if (rl_fd == -1) { if (attach_ls_data(db.fra_pos, db.fsa_pos, db.special_flag, YES) == INCORRECT) { (void)ftp_quit(); exit(INCORRECT); } } } #else if (rl_fd == -1) { if (attach_ls_data(db.fra_pos, db.fsa_pos, db.special_flag, YES) == INCORRECT) { (void)ftp_quit(); exit(INCORRECT); } } if ((fra[db.fra_pos].stupid_mode == YES) || (fra[db.fra_pos].remove == YES)) { /* * If all files from the previous listing have been * collected, lets reset the ls_data structure or otherwise * it keeps on growing forever. */ # ifdef LOCK_DEBUG if (lock_region(rl_fd, LOCK_RETR_PROC, __FILE__, __LINE__) == LOCK_IS_NOT_SET) # else if (lock_region(rl_fd, LOCK_RETR_PROC) == LOCK_IS_NOT_SET) # endif { if (reset_ls_data(db.fra_pos) == INCORRECT) { (void)ftp_quit(); exit(INCORRECT); } } # ifdef LOCK_DEBUG unlock_region(rl_fd, LOCK_RETR_PROC, __FILE__, __LINE__); # else unlock_region(rl_fd, LOCK_RETR_PROC); # endif } #endif if ((fra[db.fra_pos].ignore_file_time != 0) || (fra[db.fra_pos].delete_files_flag & UNKNOWN_FILES)) { /* Note: FTP returns GMT so we need to convert this to GMT! */ current_time = time(NULL); p_tm = gmtime(¤t_time); current_time = mktime(p_tm); } /* * Evaluate the list from the LIST command. */ p_end = list; do { p_start = p_end; while ((*p_end != '\r') && (*p_end != '\n') && (*p_end != '\0')) { p_end++; } if ((ftpparse(&fp, &file_size, &file_mtime, p_start, p_end - p_start) == 1) && ((fp.flagtryretr == 1) && ((fp.name[0] != '.') || (fra[db.fra_pos].dir_flag & ACCEPT_DOT_FILES)))) { list_length++; list_size += file_size; if (fp.namelen < MAX_FILENAME_LENGTH) { /* Store file name */ (void)memcpy(file_name, fp.name, fp.namelen); file_name[fp.namelen] = '\0'; if (fra[db.fra_pos].dir_flag == ALL_DISABLED) { delete_remote_file(FTP, file_name, fp.namelen, #ifdef _DELETE_LOG DELETE_HOST_DISABLED, #endif &files_deleted, &file_size_deleted, file_size); } else { gotcha = NO; for (k = 0; k < nfg; k++) { p_mask = fml[k].file_list; for (j = 0; j < fml[k].fc; j++) { if ((status = pmatch(p_mask, file_name, NULL)) == 0) { if (check_list(file_name, file_size, file_mtime, &files_to_retrieve, file_size_to_retrieve, more_files_in_list) == 0) { gotcha = YES; } else { gotcha = NEITHER; } break; } else if (status == 1) { /* This file is definitly NOT wanted! */ /* Lets skip the rest of this group. */ break; } #ifdef SHOW_FILTER_MISSES if ((status == -1) || (fsa->debug > NORMAL_MODE)) { char tmp_mask[MAX_FILENAME_LENGTH]; if (expand_filter(p_mask, tmp_mask, time(NULL)) == YES) { trans_db_log(INFO_SIGN, __FILE__, __LINE__, NULL, "%s (%s) not fitting %s", p_mask, tmp_mask, file_name); } else { trans_db_log(INFO_SIGN, __FILE__, __LINE__, NULL, "%s not fitting %s", p_mask, file_name); } } #endif NEXT(p_mask); } if ((gotcha == YES) || (gotcha == NEITHER)) { break; } } if ((gotcha == NO) && (status != 0) && (fra[db.fra_pos].delete_files_flag & UNKNOWN_FILES)) { time_t diff_time = current_time - file_mtime; if ((fra[db.fra_pos].unknown_file_time == -2) || ((diff_time > fra[db.fra_pos].unknown_file_time) && (diff_time > DEFAULT_TRANSFER_TIMEOUT))) { delete_remote_file(FTP, file_name, fp.namelen, #ifdef _DELETE_LOG DEL_UNKNOWN_FILE, #endif &files_deleted, &file_size_deleted, file_size); } } } } else { (void)memcpy(file_name, fp.name, MAX_FILENAME_LENGTH); file_name[MAX_FILENAME_LENGTH] = '\0'; trans_log(ERROR_SIGN, __FILE__, __LINE__, NULL, NULL, "Remote file name `%s' is to long, it may only be %d bytes long.", file_name, MAX_FILENAME_LENGTH); } } while ((*p_end == '\r') || (*p_end == '\n')) { p_end++; } } while (*p_end != '\0'); free(list); /* Free file mask list. */ for (i = 0; i < nfg; i++) { free(fml[i].file_list); } free(fml); } if (files_deleted > 0) { trans_log(DEBUG_SIGN, NULL, 0, NULL, NULL, #if SIZEOF_OFF_T == 4 "%d files %ld bytes found for retrieving %s[%u files with %ld bytes in %s (deleted %u files with %ld bytes)]. @%x", #else "%d files %lld bytes found for retrieving %s[%u files with %lld bytes in %s (deleted %u files with %lld bytes)]. @%x", #endif files_to_retrieve, (pri_off_t)(*file_size_to_retrieve), (*more_files_in_list == YES) ? "(+) " : "", list_length, (pri_off_t)list_size, (db.target_dir[0] == '\0') ? "home dir" : db.target_dir, files_deleted, (pri_off_t)file_size_deleted, db.id.dir); } else { trans_log(DEBUG_SIGN, NULL, 0, NULL, NULL, #if SIZEOF_OFF_T == 4 "%d files %ld bytes found for retrieving %s[%u files with %ld bytes in %s]. @%x", #else "%d files %lld bytes found for retrieving %s[%u files with %lld bytes in %s]. @%x", #endif files_to_retrieve, (pri_off_t)(*file_size_to_retrieve), (*more_files_in_list == YES) ? "(+) " : "", list_length, (pri_off_t)list_size, (db.target_dir[0] == '\0') ? "home dir" : db.target_dir, db.id.dir); } /* * Remove all files from the remote_list structure that are not * in the current buffer. */ if ((fra[db.fra_pos].stupid_mode != YES) && (fra[db.fra_pos].remove == NO)) { int files_removed = 0, i; size_t move_size; for (i = 0; i < (no_of_listed_files - files_removed); i++) { if (rl[i].in_list == NO) { int j = i; while ((rl[j].in_list == NO) && (j < (no_of_listed_files - files_removed))) { j++; } if (j != (no_of_listed_files - files_removed)) { move_size = (no_of_listed_files - files_removed - j) * sizeof(struct retrieve_list); (void)memmove(&rl[i], &rl[j], move_size); } files_removed += (j - i); } } if (files_removed > 0) { int current_no_of_listed_files = no_of_listed_files; size_t new_size, old_size; no_of_listed_files -= files_removed; if (no_of_listed_files < 0) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Hmmm, no_of_listed_files = %d", no_of_listed_files); no_of_listed_files = 0; } if (no_of_listed_files == 0) { new_size = (RETRIEVE_LIST_STEP_SIZE * sizeof(struct retrieve_list)) + AFD_WORD_OFFSET; } else { new_size = (((no_of_listed_files / RETRIEVE_LIST_STEP_SIZE) + 1) * RETRIEVE_LIST_STEP_SIZE * sizeof(struct retrieve_list)) + AFD_WORD_OFFSET; } old_size = (((current_no_of_listed_files / RETRIEVE_LIST_STEP_SIZE) + 1) * RETRIEVE_LIST_STEP_SIZE * sizeof(struct retrieve_list)) + AFD_WORD_OFFSET; if (old_size != new_size) { char *ptr; ptr = (char *)rl - AFD_WORD_OFFSET; #ifdef DO_NOT_PARALLELIZE_ALL_FETCH if ((fra[db.fra_pos].stupid_mode == YES) || (fra[db.fra_pos].remove == YES)) { if ((ptr = realloc(ptr, new_size)) == NULL) { system_log(ERROR_SIGN, __FILE__, __LINE__, "realloc() error : %s", strerror(errno)); (void)ftp_quit(); exit(INCORRECT); } } else { #endif if ((ptr = mmap_resize(rl_fd, ptr, new_size)) == (caddr_t) -1) { system_log(ERROR_SIGN, __FILE__, __LINE__, "mmap_resize() error : %s", strerror(errno)); (void)ftp_quit(); exit(INCORRECT); } rl_size = new_size; #ifdef DO_NOT_PARALLELIZE_ALL_FETCH } #endif ptr += AFD_WORD_OFFSET; rl = (struct retrieve_list *)ptr; } *(int *)((char *)rl - AFD_WORD_OFFSET) = no_of_listed_files; } } } return(files_to_retrieve); }
bool ChooseAnImageFTP(int sx,int sy, char *ftp_dir, int slot, char **filename, bool *isdir, int *index_file) { /* Parameters: sx, sy - window size, ftp_dir - what FTP directory to use, slot - in what slot should an image go (common: #6 for 5.25' 140Kb floppy disks, and #7 for hard-disks). slot #5 - for 800Kb floppy disks, but we do not use them in Apple][? (They are as a rule with .2mg extension) index_file - from which file we should start cursor (should be static and 0 when changing dir) Out: filename - chosen file name (or dir name) isdir - if chosen name is a directory */ double facx = double(g_ScreenWidth) / double(SCREEN_WIDTH); double facy = double(g_ScreenHeight) / double(SCREEN_HEIGHT); SDL_Surface *my_screen; // for background struct ftpparse FTP_PARSE; // for parsing ftp directories #ifndef _WIN32 struct stat info; #endif if(font_sfc == NULL) if(!fonts_initialization()) return false; //if we don't have a fonts, we just can do none char tmpstr[512]; char ftpdirpath [MAX_PATH]; snprintf(ftpdirpath, MAX_PATH, "%s/%s%s", g_sFTPLocalDir, g_sFTPDirListing, md5str(ftp_dir)); // get path for FTP dir listing // printf("Dir: %s, MD5(dir)=%s\n",ftp_dir,ftpdirpath); List<char> files; // our files List<char> sizes; // and their sizes (or 'dir' for directories) int act_file; // current file int first_file; // from which we output files char ch = 0; // prepare screen SDL_Surface *tempSurface; if(!g_WindowResized) { if(g_nAppMode == MODE_LOGO) tempSurface = g_hLogoBitmap; // use logobitmap else tempSurface = g_hDeviceBitmap; } else tempSurface = g_origscreen; my_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, tempSurface->w, tempSurface->h, tempSurface->format->BitsPerPixel, 0, 0, 0, 0); if(tempSurface->format->palette && my_screen->format->palette) SDL_SetColors(my_screen, tempSurface->format->palette->colors, 0, tempSurface->format->palette->ncolors); surface_fader(my_screen, 0.2F, 0.2F, 0.2F, -1, 0); // fade it out to 20% of normal SDL_BlitSurface(tempSurface, NULL, my_screen, NULL); SDL_BlitSurface(my_screen, NULL, screen, NULL); // show background // ch = 0; #define NORMAL_LENGTH 60 if(strlen(ftp_dir) > NORMAL_LENGTH) { ch = ftp_dir[NORMAL_LENGTH]; ftp_dir[NORMAL_LENGTH] = 0;} //cut-off too long string font_print_centered(sx/2 ,5 * facy , ftp_dir, screen, 1.5 * facx, 1.3 * facy); if(ch) ftp_dir[NORMAL_LENGTH] = ch; //restore cut-off char font_print_centered(sx/2,20 * facy,"Connecting to FTP server... Please wait.", screen, 1 * facx, 1 * facy); SDL_Flip(screen); // show the screen bool OKI; #ifndef _WIN32 if(stat(ftpdirpath,&info) == 0 && info.st_mtime > time(NULL) - RENEW_TIME) { OKI = false; // use this file } else { OKI = ftp_get(ftp_dir,ftpdirpath); // get ftp dir listing } #else // in WIN32 let's use constant caching? -- need to be redone using file.mtime if(GetFileAttributes(ftpdirpath) != DWORD(-1)) OKI = false; else OKI = ftp_get(ftp_dir,ftpdirpath); // get ftp dir listing #endif if(OKI) { // error printf("Failed getting FTP directory %s to %s\n",ftp_dir,ftpdirpath); font_print_centered(sx/2,30 * facy, "Failure. Press any key!",screen, 1.4 * facx, 1.1 * facy); SDL_Flip(screen); // show the screen SDL_Delay(KEY_DELAY); // wait some time to be not too fast ////////////////////////////////// // Wait for keypress ////////////////////////////////// SDL_Event event; // event Uint8 *keyboard; // key state event.type = SDL_QUIT; while(event.type != SDL_KEYDOWN) { // wait for key pressed SDL_Delay(100); SDL_PollEvent(&event); } SDL_FreeSurface(my_screen); return false; } FILE *fdir = fopen(ftpdirpath,"r"); char *tmp; int i,j, B, N; // for cycles, beginning and end of list // build prev dir if(strcmp(ftp_dir, "ftp://")) { tmp = new char[3]; strcpy(tmp, ".."); files.Add(tmp); tmp = new char[5]; strcpy(tmp, "<UP>"); sizes.Add(tmp); // add sign of directory B = 1; } else B = 0; // for sorting dirs while (tmp = fgets(tmpstr,512,fdir)) // first looking for directories { // clear and then try to fill in FTP_PARSE struct memset(&FTP_PARSE,0,sizeof(FTP_PARSE)); ftpparse(&FTP_PARSE, tmp, strlen(tmp)); int what = getstatFTP(&FTP_PARSE, NULL); if (strlen(FTP_PARSE.name) > 0 && what == 1) // is directory! { tmp = new char[strlen(FTP_PARSE.name)+1]; // add entity to list strcpy(tmp, FTP_PARSE.name); files.Add(tmp); tmp = new char[6]; strcpy(tmp, "<DIR>"); sizes.Add(tmp); // add sign of directory } /* if */ } // sort directories. Please, don't laugh at my bubble sorting - it the simplest thing I've ever seen --bb if(files.Length() > 2) { N = files.Length() - 1; // B = 1; - defined above for(i = N; i > B; i--) for(j = B; j < i; j++) if(strcasecmp(files[j], files[j + 1]) > 0) { files.Swap(j,j + 1); sizes.Swap(j,j + 1); } } B = files.Length(); // start for files (void) rewind (fdir); // to the start // now get all regular files while (tmp = fgets(tmpstr,512,fdir)) { int fsize; // clear and then try to fill in FTP_PARSE struct memset(&FTP_PARSE,0,sizeof(FTP_PARSE)); ftpparse(&FTP_PARSE, tmp, strlen(tmp)); if ((getstatFTP(&FTP_PARSE, &fsize) == 2)) // is normal file! { tmp = new char[strlen(FTP_PARSE.name)+1]; // add this entity to list strcpy(tmp, FTP_PARSE.name); files.Add(tmp); tmp = new char[10]; // 1400000KB snprintf(tmp, 9, "%dKB", fsize); sizes.Add(tmp); // add this size to list } /* if */ } (void) fclose (fdir); // do sorting for files if(files.Length() > 2 && B < files.Length()) { N = files.Length() - 1; // B = 1; for(i = N; i > B; i--) for(j = B; j < i; j++) if(strcasecmp(files[j], files[j + 1]) > 0) { files.Swap(j,j + 1); sizes.Swap(j,j + 1); } } // Count out cursor position and file number output act_file = *index_file; if(act_file >= files.Length()) act_file = 0; // cannot be more than files in list first_file = act_file - (FILES_IN_SCREEN / 2); if (first_file < 0) first_file = 0; // cannot be negativ... // Show all directories (first) and files then // char *tmp; char *siz; // int i; while(true) { SDL_BlitSurface(my_screen, NULL, screen, NULL); // show background font_print_centered(sx/2 ,5 * facy , ftp_dir, screen, 1.5 * facx, 1.3 * facy); if (slot == 6) font_print_centered(sx/2,20 * facy,"Choose image for floppy 140KB drive", screen, 1 * facx, 1 * facy); else if (slot == 7) font_print_centered(sx/2,20 * facy,"Choose image for Hard Disk", screen, 1 * facx, 1 * facy); else if (slot == 5) font_print_centered(sx/2,20 * facy,"Choose image for floppy 800KB drive", screen, 1 * facx, 1 * facy); else if (slot == 1) font_print_centered(sx/2,20 * facy,"Select file name for saving snapshot", screen, 1 * facx, 1 * facy); else if (slot == 0) font_print_centered(sx/2,20 * facy,"Select snapshot file name for loading", screen, 1 * facx, 1 * facy); font_print_centered(sx/2,30 * facy, "Press ENTER to choose, or ESC to cancel",screen, 1.4 * facx, 1.1 * facy); files.Rewind(); // from start sizes.Rewind(); i = 0; // printf("We've printed some messages, go to file list!\n"); // show all fetched dirs and files // topX of first fiel visible int TOPX = 45 * facy; while(files.Iterate(tmp)) { sizes.Iterate(siz); // also fetch size string if (i >= first_file && i < first_file + FILES_IN_SCREEN) { // FILES_IN_SCREEN items on screen // char tmp2[80],tmp3[256]; if (i == act_file) { // show item under cursor (in inverse mode) SDL_Rect r; r.x= 2; r.y= TOPX + (i-first_file) * 15 * facy - 1; if(strlen(tmp) > 46) r.w = 46 * 6 * 1.7 * facx + 2; else r.w= strlen(tmp) * 6 * 1.7 * facx + 2; // 6- FONT_SIZE_X r.h= 9 * 1.5 * facy; SDL_FillRect(screen, &r, SDL_MapRGB(screen->format,255,0,0));// in RED } /* if */ // print file name with enlarged font ch = 0; if(strlen(tmp) > 46) { ch = tmp[46]; tmp[46] = 0;} //cut-off too long string font_print(4, TOPX + (i - first_file) * 15 * facy, tmp, screen, 1.7 * facx, 1.5 * facy); // show name font_print(sx - 70*facx, TOPX + (i - first_file) * 15 * facy, siz, screen, 1.7 * facx, 1.5 * facy);// show info (dir or size) if(ch) tmp[46] = ch; //restore cut-off char } /* if */ i++; // next item } /* while */ ///////////////////////////////////////////////////////////////////////////////////////////// // draw rectangles rectangle(screen, 0, TOPX - 5, g_ScreenWidth, 320 * facy, SDL_MapRGB(screen->format, 255, 255, 255)); rectangle(screen, 480 * facx, TOPX - 5, 0, 320 * facy, SDL_MapRGB(screen->format, 255, 255, 255)); SDL_Flip(screen); // show the screen SDL_Delay(KEY_DELAY); // wait some time to be not too fast ////////////////////////////////// // Wait for keypress ////////////////////////////////// SDL_Event event; // event Uint8 *keyboard; // key state event.type = SDL_QUIT; while(event.type != SDL_KEYDOWN) { // wait for key pressed SDL_Delay(10); SDL_PollEvent(&event); } // control cursor keyboard = SDL_GetKeyState(NULL); // get current state of pressed (and not pressed) keys if (keyboard[SDLK_UP] || keyboard[SDLK_LEFT]) { if (act_file>0) act_file--; // up one position if (act_file<first_file) first_file=act_file; } /* if */ if (keyboard[SDLK_DOWN] || keyboard[SDLK_RIGHT]) { if (act_file < (files.Length() - 1)) act_file++; if (act_file >= (first_file + FILES_IN_SCREEN)) first_file=act_file - FILES_IN_SCREEN + 1; } /* if */ if (keyboard[SDLK_PAGEUP]) { act_file-=FILES_IN_SCREEN; if (act_file<0) act_file=0; if (act_file<first_file) first_file=act_file; } /* if */ if (keyboard[SDLK_PAGEDOWN]) { act_file+=FILES_IN_SCREEN; if (act_file>=files.Length()) act_file=(files.Length()-1); if (act_file>=(first_file+FILES_IN_SCREEN)) first_file=act_file-FILES_IN_SCREEN + 1; } /* if */ // choose an item? if (keyboard[SDLK_RETURN]) { // dup string from selected file name *filename = strdup(php_trim(files[act_file],strlen(files[act_file]))); // printf("files[act_file]=%s, *filename=%s\n\n", files[act_file], *filename); if(!strcmp(sizes[act_file], "<DIR>") || !strcmp(sizes[act_file], "<UP>")) *isdir = true; else *isdir = false; // this is directory (catalog in Apple][ terminology) *index_file = act_file; // remember current index files.Delete(); sizes.Delete(); SDL_FreeSurface(my_screen); return true; } /* if */ if (keyboard[SDLK_ESCAPE]) { files.Delete(); sizes.Delete(); SDL_FreeSurface(my_screen); return false; // ESC has been pressed } /* if */ if (keyboard[SDLK_HOME]) { // HOME? act_file=0; first_file=0; } /* if */ if (keyboard[SDLK_END]) { // END? act_file=files.Length() - 1; // go to the last possible file in list first_file=act_file - FILES_IN_SCREEN + 1; if(first_file < 0) first_file = 0; } /* if */ } } /* ChooseAnImageFTP */
/** \brief Parse (part of) a dirlisting into a list of filesystem nodes. * This functionality is used by RecursiveDownloadJob also. */ size_t DirListJob::ParseDirListData( const char* pzBuf, size_t nSize, std::vector< RemoteNode >* pacList ) { struct ftpparse sData; memset( &sData, 0, sizeof( sData ) ); size_t nTotalRead = 0; // Total bytes read. String zLine = m_zLastLineFragment; // Copy the last fragment read if we didn't read a complete line at the end last time. size_t nLineLength = m_zLastLineFragment.size(); // Initialize the current line length. const char* pzLine = pzBuf; // Read in the next line up to and excluding the '\n' nTotalRead = strnchr( pzLine, nSize, '\n' ) - pzLine; nLineLength += nTotalRead; // Append the new text to the end of the line. zLine += String( pzLine, nTotalRead ); /* Didn't find a \n; the line is incomplete so save it for later */ if( nTotalRead == nSize ) { m_zLastLineFragment = zLine; return( nSize ); } do { // DEBUG( "pzBuf: %x pzLine: %x length: %i pzLine - pzBuf: %i\n", pzBuf, pzLine, nLineLength, pzLine - pzBuf ); // DEBUG( "Line: '%s' length: %i\n", zLine.c_str(), nLineLength ); // Attempt to parse the current line. int nResult; nResult = ftpparse( &sData, zLine.c_str(), nLineLength ); // DEBUG( "Parse result: %i\n", nResult ); if( nResult == 1 ) /* 1 indicates success */ { // Create a new RemoteNode for the directory entry. RemoteNode cNode; cNode.m_zName = String( sData.name, sData.namelen ); cNode.m_bIsDir = sData.flagtrycwd; cNode.m_nSize = sData.size; cNode.m_cTimestamp = DateTime( sData.mtime ); cNode.m_zPath.Format( "%s/%s", m_zRemotePath.c_str(), cNode.m_zName.c_str() ); /* ftpparse doesn't provide permissions! Guess we'll do without for now. */ cNode.m_nPermissions = 0777; // DEBUG( "Parsed: name '%s', path '%s', size %i, %s, %s\n", cNode.m_zName.c_str(), cNode.m_zPath.c_str(), cNode.m_nSize, (cNode.m_bIsDir?"dir":"file"), cNode.m_cTimestamp.GetDate().c_str() ); pacList->push_back( cNode ); } else { String zTmp = String( pzLine, nLineLength ); DEBUG( "ParseDirListing: ftpparse() failed on '%s' (%i bytes)\n", zTmp.c_str(), nLineLength ); } nTotalRead++; /* Skip the \n */ pzLine = pzBuf + nTotalRead; nLineLength = strnchr( pzLine, nSize - nTotalRead, '\n' ) - pzLine; nTotalRead += nLineLength; zLine = String( pzLine, nLineLength ); /* Save anything after the last \n (this will be empty if the pzBuf ends with \n) */ if( nTotalRead >= nSize ) { m_zLastLineFragment = zLine; break; } } while( 1 ); // DEBUG( " nTotalRead: %i nSize: %i zLastLineFragment: '%s'\n", nTotalRead, nSize, m_zLastLineFragment.c_str() ); return( nSize ); }