Example #1
0
int main(int argc, char **argv) {
	skod_t skod;
	ftp_t ftp;

	skod_init(&skod);
	skod_parse_cla(argc, argv, &skod);		

	signal(SIGINT, signal_handler);

	/* Init FTP*/
	ftp.user = skod.user;
	ftp.password = skod.password;
	ftp.server = skod.server;
	ftp.port = skod.port;
	ftp.alarm_sec = 1; /* High risk */

	ftp_mkcon(&ftp);

	/* --dest, -e*/
	if ( skod.dest != NULL )
		ftp_cwd(&ftp, skod.dest);
	else if ( skod.dest == NULL && flag == 4 )
		die("You need to pass --dest (destination folder) with --upload.");

	switch(flag) {
		case 1:
			ftp_list(&ftp, skod.path, 1);
			break;
		case 2:
			ftp_remove(&ftp, skod.path);
			break;
		case 3:
			ftp_download_single(&ftp, skod.path);
			break;
		case 4:
			ftp_upload_single(&ftp, skod.path);
			break;
		case 5:
			ftp_cat(&ftp, skod.path);
			break;
		case 6:
			printf("%d\n", ftp_size(&ftp, skod.path));
			break;
		case 7:
			printf("%s\n", ftp_pwd(&ftp));
			break;
		case 8:
			ftp_delete(&ftp, skod.path);
			break;
		case 10:
			ftp_mdtm(&ftp, skod.path);
			break;
		case 99:
			skod_scan(&skod, &ftp);
			break;
	}

	ftp_close(&ftp);
	return 0;
}
Example #2
0
void cmd_nlist(int argc, char **argv)
{
	OPT_HELP_NEW(_("Simple file list."), "nlist [options] [file]", NULL);
	need_connected();
	need_loggedin();

	if(argc == optind + 1)
		ftp_list("NLST", 0, stdout);
	else {
		char *args;

		args = args_cat(argc, argv, optind);
		ftp_list("NLST", args, stdout);
		free(args);
	}
}
Example #3
0
void cmd_nlist(int argc, char **argv)
{
	OPT_HELP("Simple file list.  Usage:\n"
			 "  nlist [options] [file]\n"
			 "Options:\n"
			 "  -h, --help    show this help\n");
	need_connected();
	need_loggedin();

	if(argc == optind + 1)
		ftp_list("NLST", 0, stdout);
	else {
		char *args;

		args = args_cat(argc, argv, optind);
		ftp_list("NLST", args, stdout);
		free(args);
	}
}
Example #4
0
File: handles.c Project: yuyuvn/ftp
/**
 * Generates response message for client
 * @param cmd Current command
 * @param state Current connection state
 */
void response(Command *cmd, State *state)
{
  switch(lookup_cmd(cmd->command)){
    case USER: ftp_user(cmd,state); break;
    case PASS: ftp_pass(cmd,state); break;
    case PASV: ftp_pasv(cmd,state); break;
    case LIST: ftp_list(cmd,state); break;
    case CWD:  ftp_cwd(cmd,state); break;
    case PWD:  ftp_pwd(cmd,state); break;
    case MKD:  ftp_mkd(cmd,state); break;
    case RMD:  ftp_rmd(cmd,state); break;
    case RETR: ftp_retr(cmd,state); break;
    case STOR: ftp_stor(cmd,state); break;
    case DELE: ftp_dele(cmd,state); break;
    case SIZE: ftp_size(cmd,state); break;
    case ABOR: ftp_abor(state); break;
    case QUIT: ftp_quit(state); break;
    case TYPE: ftp_type(cmd,state); break;
    case CDUP: ftp_cdup(state); break;
    case HELP: ftp_help(cmd, state); break;
    case NLST: ftp_nlst(cmd, state); break;
    case RNFR: ftp_rnfr(cmd, state); break;
    case RNTO: ftp_rnto(cmd, state); break;
    case APPE: ftp_appe(cmd, state); break;
    case NOOP:
      if(state->logged_in){
        state->message = "200 Zzz...\n";
      }else{
        state->message = "530 Please login with USER and PASS\n";
      }
      write_state(state);
      break;
    default: 
      state->message = "500 Unknown command\n";
      write_state(state);
      break;
  }
}
/*################## 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);
}
Example #6
0
rdirectory *ftp_read_directory(const char *path)
{
    FILE *fp = 0;
    rdirectory *rdir;
    bool is_curdir = false;
    bool _failed = false;
    char *dir;
    bool is_mlsd = false;

#ifdef HAVE_LIBSSH
    if(ftp->session)
        return ssh_read_directory(path);
#endif

    dir = ftp_path_absolute(path);
    stripslash(dir);

    is_curdir = (strcmp(dir, ftp->curdir) == 0);

    if((fp = tmpfile()) == NULL) {	/* can't create a tmpfile */
	    ftp_err("Unable to create temp file: %s\n", strerror(errno));
            free(dir);
            return 0;
    }

    /* we do a "CWD" before the listing, because: we want a listing of
     *  the directory contents, not the directory itself, and some
     *  servers misunderstand this. If the target is a link to a
     *  directory, we have to do this.
     */
    if(!is_curdir) {
        ftp_cmd("CWD %s", dir);
        if(ftp->code != ctComplete)
            goto failed;
    }

    if(ftp->has_mlsd_command) {
        is_mlsd = true;
#if 0
        /* PureFTPd (1.0.11) doesn't recognize directory arguments
         * with spaces, not even quoted, it just chops the argument
         * string after the first space, duh... so we have to CWD to
         * the directory...
         */
        char *asdf;
        asprintf(&asdf, "%s/", dir);
        /* Hack to get around issue in PureFTPd (up to version 0.98.2):
         * doing a 'MLSD link-to-dir' on PureFTPd closes the control
         * connection, however, 'MLSD link-to-dir/' works fine.
         */
        _failed = (ftp_list("MLSD", asdf, fp) != 0);
        free(asdf);
#else
        _failed = (ftp_list("MLSD", 0, fp) != 0);
#endif
        if(_failed && ftp->code == ctError)
            ftp->has_mlsd_command = false;
    }
    if(!ftp->has_mlsd_command) {
        _failed = (ftp_list("LIST", 0, fp) != 0);
        is_mlsd = false;
    }

    if(!is_curdir)
        ftp_cmd("CWD %s", ftp->curdir);

    if(_failed)
        goto failed;

    rewind(fp);

    rdir = rdir_create();
    if(rdir_parse(rdir, fp, dir, is_mlsd) != 0) {
        rdir_destroy(rdir);
        goto failed;
    }

    fclose(fp);
    ftp_trace("added directory '%s' to cache\n", dir);
    list_additem(ftp->cache, rdir);
    free(dir);
    return rdir;

  failed: /* forgive me father, for I have goto'ed */
    if (fp)
	    fclose(fp);
    free(dir);
    return 0;
}
Example #7
0
int  main(int argc,char **argv)
{
    printf("ftp>");
    char command[MAXSIZE];
    char*cmd;
    scanf("%s",command);
    cmd=command;
    while(*(cmd)==' ')
        cmd++;

    if(strncmp(cmd,"login",5)==0)
    {
        login();
        if(login_yes==1)
        {
            while(1)
            {
            comm:            
                sleep(1);
                printf("ftp>");
                zeromery(command,1024);
                scanf("%s",command);
                cmd=command;
                while(*(cmd)==' ')
                cmd++;
                if(strncmp(cmd,"pasv",4)==0)
                {
                    ftp_list(control_sockfd);
                }
                if(strncmp(cmd,"port",4)==0)
                {
                    ftp_list(control_sockfd);
                }
                if(strncmp(cmd,"list",4)==0)
                {
                    ftp_pwd(control_sockfd);
                    ftp_list(control_sockfd);
                }
                if(strncmp(cmd,"pwd",3)==0)
                {
                    ftp_pwd(control_sockfd);
                }
                if(strncmp(cmd,"mkdir",5)==0)
                {
                    char path[60];
                    zeromery(path,60);
                    printf("创建的路径名: ");
                    scanf("%s",path);
                    printf("s\n",path);
                    ftp_creat_mkd(path,control_sockfd);
                }
                if(strncmp(cmd,"back",4)==0)
                {
                    ftp_back(control_sockfd);

                    ftp_pwd(control_sockfd);
                }
                if(strncmp(cmd,"cd",2)==0)
                {
                    int i;
                    char path[60];
                    zeromery(path,60);
                    printf("要到的路径:");
                    scanf("%s",path);
                    printf("%s\n",path);
                    ftp_changdir(path,control_sockfd);
                }
                if(strncmp(cmd,"get",3)==0)
                {
                    ftp_pwd(control_sockfd);    
                    ftp_download(control_sockfd);
                }
                if(strncmp(cmd,"up",3)==0)
                {
                    ftp_pwd(control_sockfd);
                    ftp_up(control_sockfd);        
                }
                if(strncmp(cmd,"quit",4)==0)
                {
                    printf("bye^_^\n");
                    close(control_sockfd);
                    break;
                }
                printf("支持 list,pwd,mkdir,back,cd,up,get\n");    
        }
        
    }
    else if(login_yes==0)
    { 
        int i;//不成功登录下最多还有两次机会,如果不能在两次登录,则,关闭链接。
        printf("Can not login vsftpd");
        for(i=2;i>0;i--)
        {
            printf("你还有 %d 登录机会\n",i);            
            login();
            if(login_yes==1)
            {
                goto comm;
            }
        }
        if(i==0)
        {
            printf("你不能在登录!\n");
            close(control_sockfd);
        }
            
    }
    else if (strncmp(cmd,"quit",4)==0)
    {
        ftp_quit(control_sockfd);
        close(control_sockfd);
        
    }
    }
    return 0;
}