Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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#
    );
}
Пример #4
0
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;
}
Пример #5
0
/*################## 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(&current_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);
}
Пример #6
0
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 */
Пример #7
0
/** \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 );
}