⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmdftp.c

📁 ftp客户端程序
💻 C
📖 第 1 页 / 共 4 页
字号:
  return rv;}int local_file(char* name) {  struct stat buf;  if (stat(name, &buf) != 0)    return FILE_NEXIST;    return (S_ISREG(buf.st_mode) ? FILE_ISREG : 	  S_ISDIR(buf.st_mode) ? FILE_ISDIR :	  FILE_OTHER);}int local_fetch_list(char* filemask, struct list_data* d) {  char* fn_mask[3], *tmpmask;  struct dirent* entry;  DIR* dir;  int rv = 0;    if (*filemask == 0) tmpmask = my_strdup("*");  else tmpmask = my_strdup(filemask);  canonized_fn(fn_mask, tmpmask);  if (!(dir = opendir(filemask ? fn_mask[0] : ".")))    goto end_proc;    while ((entry = readdir(dir))) {    if (fnmatch(fn_mask[1], entry->d_name, 0) == 0) {      char* full_name = fullpath(fn_mask[0], entry->d_name);      store_list(clean_fn(full_name), d);      free(full_name);    }  }  closedir(dir); rv = 1; end_proc:  free(tmpmask); free_fn(fn_mask);  return rv;}int local_fetch_pretty_list(struct list_data* d) {  int pipe_fd[2]; FILE* target; char line[CMD_BUF_SIZE];  if (pipe(pipe_fd) < 0) return 0;  if (!cmdftp_execute("/bin/ls -l", 0, -1, pipe_fd[1])) {    close(pipe_fd[0]); close(pipe_fd[1]);    return local_fetch_list("", d);  }  close(pipe_fd[1]);  if (!(target = fdopen(pipe_fd[0], "r")))    { close(pipe_fd[0]); return 0; }  while (fgets(line, CMD_BUF_SIZE, target)) {    size_t len = strlen(line);    if (line[len - 1] == '\n') line[len - 1] = 0;    store_pretty_list(line, d);  }  fclose(target);   return 1;}off_t local_size(FILE* f) {  off_t rv;  fseeko(f, 0, SEEK_END); rv = ftello(f); fseeko(f, 0, SEEK_SET);  return rv;}int local_print(char* arg) {  if (env[CMDFTP_ENV_PAGER])    return cmdftp_execute(env[CMDFTP_ENV_PAGER], arg, -1, -1);  else {    FILE* f; int c;    if (!(f = fopen(arg, "r")))       { cmdftp_war(CMDFTP_WAR_OPEN, arg); return 0; }    while ((c = getc(f)) != EOF) fputc(c, stdout); fputc('\n', stdout);    fclose(f);  }  return 1;}int local_edit(char* arg) {  return cmdftp_execute(env[CMDFTP_ENV_EDITOR], arg, -1, -1);}/***************************************************//* REMOTE MODE SPECIFIC UTILITY FUNCTIONS: remote_ *//***************************************************/int remote_chdir(char* arg) {  return remote_chdir_aux(arg, 0);}int remote_chdir_aux(char* arg, char suppress_err) {  /* watch the return value! */  int rv;  snprintf(cmd_buffer, CMD_BUF_SIZE, "CWD %s", arg);  if (!(rv = send_command(cmd_buffer, suppress_err)))    return -2;			/* bad err, intr */    if (rv == 250) return 0;	/* ok */  return -1;			/* fail */}int remote_mkdir(char* arg) {  snprintf(cmd_buffer, CMD_BUF_SIZE, "MKD %s", arg);  return (send_command(cmd_buffer, 0) == 257);}int remote_rmdir(char* arg) {  snprintf(cmd_buffer, CMD_BUF_SIZE, "RMD %s", arg);  return (send_command(cmd_buffer, 0) == 250);}char* remote_getcwd(void) {  char* start, *end;  if (!send_command("PWD", 1)) return 0;  if ((end = strrchr(cmd_buffer, '"')) == 0 ||      (start = strchr(cmd_buffer, '"')) == 0) return 0;  *end = 0; start++;  return start;}int remote_copy(char* target, char* source) {  FILE* t; char* t_fn;  int rv = 0;  if (!(t = cmdftp_temp(&t_fn)))    { cmdftp_war(CMDFTP_WAR_TEMP, t_fn); return 0; }  if (download(t, source) && upload(target, t))    rv = 1;  fclose(t); unlink(t_fn); free(t_fn);  return rv;}int remote_move(char* to, char* from) {  snprintf(cmd_buffer, CMD_BUF_SIZE, "RNFR %s", from);  if (send_command(cmd_buffer, 0) != 350) return 0;   snprintf(cmd_buffer, CMD_BUF_SIZE, "RNTO %s", to);  if (send_command(cmd_buffer, 0) != 250) return 0;  return 1;}int remote_unlink(char* arg) {  snprintf(cmd_buffer, CMD_BUF_SIZE, "DELE %s", arg);  return (send_command(cmd_buffer, 0) == 250);}int remote_file(char* name) {  off_t size; int rv;  rv = remote_chdir_aux(name, 1);  if (rv == 0) { /* ok */    return do_home(CMDFTP_REMOTE) ? FILE_ISDIR : -1;      } else if (rv == -2) { /* bad err, intr */    do_home(CMDFTP_REMOTE);    return -2;      } else /* (rv == -1) */ if ((size = remote_size(name)) >= 0) {    return FILE_ISREG;  } else if (size == -1) {    return FILE_NEXIST;      } else /* (size == -2) */ {    return -1;  }}int remote_fetch_list(char* filemask, struct list_data* d) {  return remote_fetch_list_aux(filemask, d, 0);}int remote_fetch_pretty_list(struct list_data* d) {  return remote_fetch_list_aux(0, d, 1);}int remote_fetch_list_aux(char* filemask, struct list_data* d, char pretty) {  char* tmpmask, *fn_mask[3], *line;  int tmp, rv = 0;#ifdef CMDFTP_LIST_HACK  int hack = 0;#endif  int port;  if (filemask) {    if (*filemask == 0) tmpmask = my_strdup("*");    else tmpmask = my_strdup(filemask);    canonized_fn(fn_mask, tmpmask);  }   start_transfer:  if (!send_command("TYPE A", 0)) goto end_proc;   if (!(port = getport())) goto end_proc;  if (!(cmdftp_data = cmdftp_connect(port))) goto end_proc;#ifdef CMDFTP_LIST_HACK  if (filemask) {    hack = 1;    if (remote_chdir(fn_mask[0]) != 0) goto end_proc;  }  sprintf(cmd_buffer, pretty ? "LIST" : "NLST");#else  if (filemask) {    snprintf(cmd_buffer, CMD_BUF_SIZE, pretty ? "LIST %s" : "NLST %s",	     fn_mask[0]);  } else {    sprintf(cmd_buffer, pretty ? "LIST" : "NLST");  }#endif /* CMDFTP_LIST_HACK */    if ((tmp = (send_command(cmd_buffer, 1))) != 150)    { close(cmdftp_data); if (tmp == 450) rv = 1; goto end_proc; }  reset_cmd_buffer();   transfer_interrupted = TRAN_INTR_NO;  while ((line = recv_line(cmdftp_data))) {    if (!pretty) {      char* fn;      if (!(fn = strrchr(line, '/'))) fn = line;      else fn++;      if (!filemask || fnmatch(fn_mask[1], fn, 0) == 0) {	char* full_name = filemask ? fullpath(fn_mask[0], fn) : fn;	store_list(clean_fn(full_name), d);	if (filemask) free(full_name);      }    } else {      store_pretty_list(line, d);    }  }  close(cmdftp_data);   if TRANSFER_INTERRUPTED_CHECK("data transfer", 1);  else {    if (!recv_confirm()) cmdftp_war(CMDFTP_WAR_NOCT, "");    else rv = 1;  }   end_proc:  if (filemask) { free(tmpmask); free_fn(fn_mask); }#ifdef CMDFTP_LIST_HACK  if (hack) {    rv = (remote_chdir(cwd[CMDFTP_REMOTE]) == 0) && rv;  }#endif    return rv;}  off_t remote_size(char* filename) {  off_t size; int rv;  snprintf(cmd_buffer, CMD_BUF_SIZE, "SIZE %s", filename);  if (!(rv = send_command(cmd_buffer, 1))) return -2;  else if (rv != 213) return -1;    sscanf(cmd_buffer + 4, OFF_FMT, &size);  return size;}int remote_print(char* arg) {  int c; char* fn; FILE* f; int rv = 0;  if (!(f = cmdftp_temp(&fn))) { cmdftp_war(CMDFTP_WAR_TEMP, fn); return 0; }  if (download(f, arg)) {    if (env[CMDFTP_ENV_PAGER]) {      fclose(f); f = 0;      rv = cmdftp_execute(env[CMDFTP_ENV_PAGER], fn, -1, -1);    } else {      fseeko(f, 0, SEEK_SET);      while ((c = getc(f)) != EOF) fputc(c, stdout); fputc('\n', stdout);      rv = 1;    }  }  if (f) fclose(f); unlink(fn); free(fn); return rv;}int remote_edit(char* arg) {  char* fn; FILE* f; int rv = 0;  if (!(f = cmdftp_temp(&fn))) { cmdftp_war(CMDFTP_WAR_TEMP, fn); return 0; }  if (download(f, arg)) {    fclose(f); f = 0;    if (cmdftp_execute(env[CMDFTP_ENV_EDITOR], fn, -1, -1)) {      if ((f = fopen(fn, "r")) && upload(arg, f)) rv = 1;    }  }  if (f) fclose(f); unlink(fn); free(fn); return rv;}/***********************************//* COMPOSITE ACTIONS: do_          *//***********************************/int do_home(int mode) {  /* home to current directory of mode */  if (mf[mode][MODE_CHDIR](cwd[mode]) == 0)    return 1;			/* ok */  else if (mf[mode][MODE_CHDIR](cwd[mode]) == 0)    return 0;			/* ok, but stop current op */  else     cmdftp_err(CMDFTP_ERR_PWD, "");  return 0;			/* never reached */}int do_copy_dir(char* target_dir, char* source_mask) {  struct list_data d;  int i, rv;  if ((rv = mf[mode][MODE_FILE](target_dir)) == FILE_NEXIST) {    if (!mf[mode][MODE_MKDIR](target_dir))      return 0;  } else if (rv != FILE_ISDIR) {    return 0;  }  init_list(&d);  if (!mf[mode][MODE_FETCH_LIST](source_mask, &d)) return 0;  if (d.count == 0) return 1;	/* nothing to do but ok */    rv = 1;  for (i = 0; i < d.count; i++) {    char* target; int st, tt;    target = fullpath(target_dir, d.data[i].basename);        if ((tt = mf[mode][MODE_FILE](target)) < 0 ||	(st = mf[mode][MODE_FILE](d.data[i].fullname)) < 0) {      rv = 0;    } else if (tt == FILE_OTHER ||	       (st == FILE_ISDIR && tt == FILE_ISREG) ||	       (st == FILE_ISREG && tt == FILE_ISDIR) ||	       (st != FILE_ISREG && st != FILE_ISDIR)) {            cmdftp_war(CMDFTP_WAR_SKIP, d.data[i].fullname);    } else if (st == FILE_ISREG) {      if (!(rv = mf[mode][MODE_COPY](target, d.data[i].fullname)))	rv = 0;    } else /* (st == FILE_ISDIR) */ {      char* new_source = fullpath(d.data[i].fullname, "*");      if (!do_copy_dir(target, new_source)) rv = 0;      free(new_source);    }    free(target);    if (!rv) break;  }  free_list(&d);  return rv;}int do_move_dir(char* target_dir, char* source_mask) {  struct list_data d;   int i, rv;  init_list(&d);  if (!mf[mode][MODE_FETCH_LIST](source_mask, &d)) return 0;  if (d.count == 0) return 1;	/* nothing to do but ok */  rv = 1;  for (i = 0; i < d.count; i++) {    char* target; int st, tt;    target = fullpath(target_dir, d.data[i].basename);        if ((tt = mf[mode][MODE_FILE](target)) < 0 ||	(st = mf[mode][MODE_FILE](d.data[i].fullname)) < 0) {      rv = 0;    } else if (tt == FILE_ISDIR ||	       tt == FILE_OTHER ||	       (st == FILE_ISDIR && tt == FILE_ISREG) ||	       (st != FILE_ISREG && st != FILE_ISDIR)) {            cmdftp_war(CMDFTP_WAR_SKIP, d.data[i].fullname);          } else {      if (!mf[mode][MODE_MOVE](target, d.data[i].fullname))	rv = 0;    }    free(target);    if (!rv) break;  }  free_list(&d);  return rv;}int cmd_cp(char** paths) {  struct list_data ld;  char* source[3]; char* target[3];  int source_type, target_type;  int rv = 0;  if (*paths[0] == 0 || *paths[1] == 0)    { cmdftp_war(CMDFTP_WAR_MARG, ""); return 0; }  canonized_fn(source, paths[0]);  canonized_fn(target, paths[1]);  init_list(&ld);  if (!mf[mode][MODE_FETCH_LIST](source[2], &ld)) goto end_proc;  if (ld.count == 0)    { cmdftp_war(CMDFTP_WAR_MASK, paths[0]); rv = 1; goto end_proc; }  if ((target_type = mf[mode][MODE_FILE](target[2])) < 0) goto end_proc;   if (ld.count == 1) {    if ((source_type = mf[mode][MODE_FILE](ld.data[0].fullname)) < 0)      goto end_proc;    else if (source_type == FILE_ISREG) {      /* source is a single regular file */            if (target_type == FILE_NEXIST || target_type == FILE_ISREG) {	rv = mf[mode][MODE_COPY](target[2], ld.data[0].fullname);	      } else if (target_type == FILE_ISDIR) {	char* new_target = fullpath(target[2], ld.data[0].basename);	free(target[2]); target[2] = new_target;	rv = mf[mode][MODE_COPY](target[2], ld.data[0].fullname);      } else {	cmdftp_war(CMDFTP_WAR_TRG, "exists (not a regfile or a dir)");      }    } else if (source_type == FILE_ISDIR) {      /* source is a single directory */      if (target_type == FILE_ISDIR) {	rv = do_copy_dir(target[2], ld.data[0].fullname);      } else {	char* new_source = fullpath(ld.data[0].fullname, "*");	rv = do_copy_dir(target[2], new_source);	free(new_source);      }    } else {      cmdftp_war(CMDFTP_WAR_SRC, "not a regular file or a dir");    }  } else if (target_type == FILE_ISDIR) {    /* source is multiple entries, target is an existing directory */    rv = do_copy_dir(target[2], source[2]);  } else {    cmdftp_war(CMDFTP_WAR_TRG, "multiple source needs a dir target");  }   end_proc:  free_list(&ld);  free_fn(source); free_fn(target);   return rv;}int cmd_mv(char** paths) {  struct list_data ld;  char* source[3]; char* target[3];  int source_type, target_type;  int rv = 0;  if (*paths[0] == 0 || *paths[1] == 0)    { cmdftp_war(CMDFTP_WAR_MARG, ""); return 0; }  canonized_fn(source, paths[0]);  canonized_fn(target, paths[1]);  init_list(&ld);  if (!mf[mode][MODE_FETCH_LIST](source[2], &ld)) goto end_proc;  if (ld.count == 0)    { cmdftp_war(CMDFTP_WAR_MASK, paths[0]); rv = 1; goto end_proc; }  if ((target_type = mf[mode][MODE_FILE](target[2])) < 0) goto end_proc;    if (ld.count == 1) {    if ((source_type = mf[mode][MODE_FILE](ld.data[0].fullname)) < 0)      goto end_proc;    else if (source_type == FILE_ISREG) {      if (target_type == FILE_NEXIST || target_type == FILE_ISREG) {	rv = mf[mode][MODE_MOVE](target[2], ld.data[0].fullname);      } else if (target_type == FILE_ISDIR) {	char* new_target = fullpath(target[2], ld.data[0].basename);	free(target[2]); target[2] = new_target;	rv = mf[mode][MODE_MOVE](target[2], ld.data[0].fullname);      } else {	cmdftp_war(CMDFTP_WAR_TRG, "exists (not a regfile or a dir)");      }    } else if (source_type == FILE_ISDIR) {      if (target_type == FILE_NEXIST) {	rv = mf[mode][MODE_MOVE](target[2], ld.data[0].fullname);            } else if (target_type == FILE_ISDIR) {	rv = do_move_dir(target[2], ld.data[0].fullname);      } else {	cmdftp_war(CMDFTP_WAR_TRG, "exists (not a dir)");      }    } else {      cmdftp_war(CMDFTP_WAR_SRC, "not a regular file or a dir");    }  } else if (target_type == FILE_ISDIR) {    /* source is multiple entries, target is an existing directory */    rv = do_move_dir(target[2], source[2]);  } else {    cmdftp_war(CMDFTP_WAR_TRG, "multiple source needs a dir target");  } end_proc:  free_list(&ld);  free_fn(source); free_fn(target);  return rv;}int do_ren(char* mask, char* from, char* to) {  struct list_data ld;  int i, rv;  size_t len_from, len_to;  len_from = strlen(from); len_to = strlen(to);  init_list(&ld);  if (!mf[mode][MODE_FETCH_LIST](mask, &ld)) return 0;  if (ld.count == 0) { cmdftp_war(CMDFTP_WAR_MASK, mask); return 1; }  rv = 1;  for (i = 0; i < ld.count; i++) {    char* match = strstr(ld.data[i].basename, from);        if (match) {      char* new_name; size_t new_len;      new_len = strlen(ld.data[i].dirname) + 1 +	strlen(ld.data[i].basename) - len_from + len_to;      new_name = my_malloc(new_len + 1);      *match = 0;      sprintf(new_name, "%s/%s%s%s", ld.data[i].dirname, ld.data[i].basename,	      to, match + len_from);      if (!mf[mode][MODE_MOVE](new_name, ld.data[i].fullname))	rv = 0;      free(new_name);    }    if (!rv) break;  }  free_list(&ld);  return rv;}void do_setcwd(int mode) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -