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

📄 cmdftp.c

📁 ftp客户端程序
💻 C
📖 第 1 页 / 共 4 页
字号:
  /* cast between function pointer types is always ok, as soon as     we remember to cast back to the right type before using one. */  char* (*fun_getcwd)(void) = (char* (*)(void))mf[mode][MODE_GETCWD];  if (cwd[mode]) free(cwd[mode]);  if ((cwd[mode] = fun_getcwd()))    cwd[mode] = my_strdup(cwd[mode]);  else if ((cwd[mode] = fun_getcwd()))    cwd[mode] = my_strdup(cwd[mode]);  else    cmdftp_err(CMDFTP_ERR_PWD, "");}/**************************************//* DISPATCHED COMMANDS                *//**************************************/int cmd_quit(char** argv) {   cmdftp_war(CMDFTP_WAR_BYE, "");  cleanexit();  return 0;			/* never reached */}int cmd_h(char** argv) {   char* arg;  int i;  arg = argv[0];  if (*arg != 0) cmdftp_war(CMDFTP_WAR_IARG, arg);  for (i = 0; i < (sizeof(msg_help) / sizeof(char*)); i += 2)    printf("%-14s %s\n", msg_help[i], msg_help[i + 1]);  return 1;}    int cmd_l(char** argv) {  char* arg;  arg = argv[0];  if (*arg != 0) cmdftp_war(CMDFTP_WAR_IARG, arg);  mode = CMDFTP_LOCAL;  return 1;}int cmd_r(char** argv) {  char* arg;  arg = argv[0];  if (*arg != 0) cmdftp_war(CMDFTP_WAR_IARG, arg);  mode = CMDFTP_REMOTE;  return 1;}int cmd_pwd(char** argv) {  char* arg;  arg = argv[0];  if (*arg != 0) cmdftp_war(CMDFTP_WAR_IARG, arg);  printf("%s\n", cwd[mode]);  return 1;}int cmd_cd(char** argv) {  char* arg;  int rv;  arg = argv[0];  if (*arg == 0) { cmdftp_war(CMDFTP_WAR_MARG, ""); return 0; }  if ((rv = mf[mode][MODE_CHDIR](arg)) == -2)    return 0;  do_setcwd(mode);  return (rv == 0);}int cmd_ren(char** argv) {  int rv;  if (*argv[0] == 0 || *argv[1] == 0)    { cmdftp_war(CMDFTP_WAR_MARG, ""); return 0; }  rv = do_ren(argv[0], argv[1], argv[2]);  return rv;}int cmd_rm(char** argv) {  char* arg;  struct list_data d;  int i, rv = 0;  arg = argv[0];  if (*arg == 0) { cmdftp_war(CMDFTP_WAR_MARG, ""); return 0; }    init_list(&d);  if (!mf[mode][MODE_FETCH_LIST](arg, &d)) return 0;  if (d.count == 0) { cmdftp_war(CMDFTP_WAR_MASK, arg); return 1; }  for (i = 0; i < d.count; i++) {    int ft;    if ((ft = mf[mode][MODE_FILE](d.data[i].fullname)) < 0 ||	(ft == FILE_ISREG && !mf[mode][MODE_UNLINK](d.data[i].fullname)))      break;    if (i == d.count - 1) rv = 1;  }  free_list(&d);  return rv;}int cmd_ls(char** argv) {  char* arg;  struct list_data d;  int rv;  arg = argv[0];  init_list(&d);  if (!mf[mode][MODE_FETCH_LIST](arg, &d)) return 0;  if (d.count == 0) { cmdftp_war(CMDFTP_WAR_MASK, arg); return 1; }  rv = ls(&d); free_list(&d); return rv;}int cmd_dir(char** argv) {  char* arg;  struct list_data d;  int rv;  arg = argv[0];  if (*arg != 0) cmdftp_war(CMDFTP_WAR_IARG, arg);  init_list(&d);  if (!mf[mode][MODE_FETCH_PRETTY_LIST](&d)) return 0;  if (d.count == 0) { cmdftp_war(CMDFTP_WAR_MASK, ""); return 1; }  rv = ls(&d); free_list(&d); return rv;}int cmd_md(char** argv) {  char* arg;  arg = argv[0];  if (*arg == 0) { cmdftp_war(CMDFTP_WAR_MARG, ""); return 0; }  return mf[mode][MODE_MKDIR](arg);}int cmd_rd(char** argv) {  char* arg;  arg = argv[0];  if (*arg == 0) { cmdftp_war(CMDFTP_WAR_MARG, ""); return 0; }  return mf[mode][MODE_RMDIR](arg);}int cmd_p(char** argv) {  char* arg;  arg = argv[0];  if (*arg == 0) { cmdftp_war(CMDFTP_WAR_MARG, ""); return 0; }  return mf[mode][MODE_PRINT](arg);}int cmd_e(char** argv) {  char* arg;  arg = argv[0];  if (*arg == 0) { cmdftp_war(CMDFTP_WAR_MARG, ""); return 0; }  if (!env[CMDFTP_ENV_EDITOR])    { cmdftp_war(CMDFTP_WAR_MENV, "EDITOR"); return 0; }  return mf[mode][MODE_EDIT](arg);}/**************************************//* UPLOAD AND DOWNLOAD                *//**************************************/int cmd_u(char** paths) {  char* source_mask;  int rv; int tt; struct list_data ld;  if (*paths[0] == 0 || *paths[1] == 0)    { cmdftp_war(CMDFTP_WAR_MARG, ""); return 0; }    if ((tt = remote_file(paths[1])) < 0)    return 0;    if (tt != FILE_NEXIST && tt != FILE_ISDIR)    { cmdftp_war(CMDFTP_WAR_TRG, "exists (not a dir)"); return 0; }  source_mask = my_strdup(paths[0]);  init_list(&ld);  if (!local_fetch_list(paths[0], &ld)) return 0;  if (ld.count == 0)    { cmdftp_war(CMDFTP_WAR_MASK, paths[0]); return 1; }    if (ld.count == 1) {    int st = local_file(ld.data[0].fullname);    if (st == FILE_ISDIR && tt == FILE_NEXIST) {       free(source_mask);      source_mask = fullpath(paths[0], "*");    }  }  free_list(&ld);  rv = u_aux(paths[1], source_mask);  free(source_mask);  return rv;}int u_aux(char* target_dir, char* source_mask) {  struct list_data ld;  char* target[3];  int i, rv;  if ((rv = remote_file(target_dir)) == FILE_NEXIST) {    if (!remote_mkdir(target_dir)) return 0;  } else if (rv != FILE_ISDIR) {    return 0;  }  init_list(&ld);  if (!local_fetch_list(source_mask, &ld)) return 0;  if (ld.count == 0) return 1;  canonized_fn(target, target_dir);  rv = 1;  for (i = 0; i < ld.count; i++) {    int file_type = local_file(ld.data[i].fullname);    if (file_type == FILE_ISREG) {      FILE* f = fopen(ld.data[i].fullname, "rb");      if (!f)	cmdftp_war(CMDFTP_WAR_OPEN, ld.data[i].fullname);      else {	char* fn;	fn = fullpath(target[2], ld.data[i].basename);	rv = upload(fn, f);	fclose(f); free(fn);      }    } else if (file_type == FILE_ISDIR) {      char* tmp_src, *tmp_trg;            tmp_src = fullpath(ld.data[i].fullname, "*");      tmp_trg = fullpath(target[2], ld.data[i].basename);            rv = u_aux(tmp_trg, tmp_src);      free(tmp_trg); free(tmp_src);    } else {      cmdftp_war(CMDFTP_WAR_SKIP, ld.data[i].fullname);    }    if (!rv) break;  }  free_list(&ld); free_fn(target);  return rv;}int upload(char* target, FILE* source) {  off_t start_pos, total_size;  char* ctarget; char* op;  size_t ctarget_len;  int port, rv;  rv = 0;   op = "Uploading";   ctarget = clean_fn(target); ctarget_len = strlen(ctarget); start_transfer:    if (!send_command("TYPE I", 0)) return 0;  if ((total_size = local_size(source)) < 0) return 0;  start_pos = 0;  if (!(port = getport())) return 0;  if (!(cmdftp_data = cmdftp_connect(port))) return 0;  snprintf(cmd_buffer, CMD_BUF_SIZE, "STOR %s", target);  if (send_command(cmd_buffer, 0) != 150) { close(cmdftp_data); return 0; }    if (!o.q)    print_progress(op, ctarget, ctarget_len, start_pos, total_size);  transfer_interrupted = TRAN_INTR_NO;  while (start_pos < total_size) {    size_t toread, bytes; ssize_t written;    toread = ((total_size - start_pos) < o.b) ? total_size - start_pos : o.b;    if (!(bytes = fread(buffer, 1, toread, source))) break;    if ((written = my_raw_write(buffer, bytes, cmdftp_data)) != bytes) break;    start_pos += bytes;    if (!o.q)      print_progress(op, ctarget, ctarget_len, start_pos, total_size);  }  if (!o.q) fputc('\n', stdout);  close(cmdftp_data);   if (start_pos < total_size) {    if (ferror(source)) cmdftp_war(CMDFTP_WAR_READ, basename(target));    else if TRANSFER_INTERRUPTED_CHECK("data transfer", 1);    else { cmdftp_err(CMDFTP_ERR_UNER, strerror(errno)); }  } else {    if (!recv_confirm()) cmdftp_war(CMDFTP_WAR_NOCT, "");    else rv = 1;  }  return rv;}int cmd_d(char** argv) {  return do_d(argv, 0);}int cmd_dr(char** argv) {  return do_d(argv, 1);}int do_d(char** paths, int resume) {  char* source_mask;  int rv; int tt; struct list_data ld;  if (*paths[0] == 0 || *paths[1] == 0)    { cmdftp_war(CMDFTP_WAR_MARG, ""); return 0; }  if ((tt = local_file(paths[1])) != FILE_NEXIST && tt != FILE_ISDIR)    { cmdftp_war(CMDFTP_WAR_TRG, "exists (not a dir)"); return 0; }  source_mask = my_strdup(paths[0]);  init_list(&ld);  if (!remote_fetch_list(paths[0], &ld)) return 0;  if (ld.count == 0)    { cmdftp_war(CMDFTP_WAR_MASK, paths[0]); return 1; }    if (ld.count == 1) {    int st = remote_file(ld.data[0].fullname);    if (st < 0) { free_list(&ld); return 0; }    if (st == FILE_ISDIR && tt == FILE_NEXIST) {       free(source_mask);      source_mask = fullpath(paths[0], "*");    }  }  free_list(&ld);    rv = d_aux(paths[1], source_mask, resume);  free(source_mask);  return rv;}int d_aux(char* target_dir, char* source_mask, int resume) {  struct list_data ld;  char* target[3];  int i, rv;  if ((rv = local_file(target_dir)) == FILE_NEXIST) {    if (!local_mkdir(target_dir)) return 0;  } else if (rv != FILE_ISDIR) {    return 0;  }  init_list(&ld);  if (!remote_fetch_list(source_mask, &ld)) return 0;  if (ld.count == 0) return 1;  canonized_fn(target, target_dir);  rv = 1;    for (i = 0; i < ld.count; i++) {    int file_type;    if ((file_type = remote_file(ld.data[i].fullname)) < 0) {      rv = 0;    } else if (file_type == FILE_ISREG) {      char* fn; FILE* f;            fn = fullpath(target[2], ld.data[i].basename);      if (!(f = fopen(fn, resume ? "ab" : "wb")))	cmdftp_war(CMDFTP_WAR_OPEN, fn);      else {	rv = download(f, ld.data[i].fullname);	fclose(f);      }      free(fn);    } else if (file_type == FILE_ISDIR) {      char* tmp_src, *tmp_trg;       tmp_src = fullpath(ld.data[i].fullname, "*");      tmp_trg = fullpath(target[2], ld.data[i].basename);      rv = d_aux(tmp_trg, tmp_src, resume);      free(tmp_trg); free(tmp_src);    } else {      cmdftp_war(CMDFTP_WAR_SKIP, ld.data[i].fullname);    }    if (!rv) break;  }  free_list(&ld); free_fn(target);  return rv;}int download(FILE* target, char* source) {  off_t start_pos, total_size;  char* csource; char* op;  size_t csource_len;  int answer, port, rv;    rv = 0;  op = "Downloading";   csource = clean_fn(source); csource_len = strlen(csource);   start_transfer:  if (!send_command("TYPE I", 0)) return 0;  if ((total_size = remote_size(source)) < 0) return 0;  if ((start_pos = ftello(target)) == -1) return 0;  if (start_pos > 0) {    snprintf(cmd_buffer, CMD_BUF_SIZE, "REST " OFF_FMT, start_pos);    if ((answer = send_command(cmd_buffer, 0)) != 350) {      cmdftp_war(CMDFTP_WAR_REST, "");      fseeko(target, 0, SEEK_SET); start_pos = 0;    }  }  if (!(port = getport())) return 0;  if (!(cmdftp_data = cmdftp_connect(port))) return 0;  snprintf(cmd_buffer, CMD_BUF_SIZE, "RETR %s", source);  if (send_command(cmd_buffer, 0) != 150) { close(cmdftp_data); return 0; }  if (!o.q)    print_progress(op, csource, csource_len, start_pos, total_size);  transfer_interrupted = TRAN_INTR_NO;  while (start_pos < total_size) {    ssize_t bytes; size_t toread, written;       toread = ((total_size - start_pos) < o.b) ? total_size - start_pos : o.b;        if ((bytes = my_raw_read(buffer, toread, cmdftp_data)) <= 0) break;    if ((written = fwrite(buffer, 1, bytes, target)) != bytes) break;        start_pos += bytes;        if (!o.q)      print_progress(op, csource, csource_len, start_pos, total_size);  }  if (!o.q) fputc('\n', stdout);  close(cmdftp_data);   if (start_pos < total_size) {    if (ferror(target))      cmdftp_war(CMDFTP_WAR_WRIT, basename(source));    else if TRANSFER_INTERRUPTED_CHECK("data transfer", 1);    else { cmdftp_err(CMDFTP_ERR_UNER, strerror(errno)); }  } else {    if (!recv_confirm()) cmdftp_war(CMDFTP_WAR_NOCT, "");    else rv = 1;  }  return rv;}/***********//* listing *//***********/int ls(struct list_data* d) {  FILE* target; int pipe_fd[2];  int i, rv = 0;  if (env[CMDFTP_ENV_PAGER]) {    if (pipe(pipe_fd) < 0) return 0;    if (!(target = fdopen(pipe_fd[1], "w")))      { close(pipe_fd[0]); close(pipe_fd[1]); return 0; }  } else target = stdout;    for (i = 0; i < d->count; i++)    fprintf(target, "%s\n", d->data[i].fullname);    if (!env[CMDFTP_ENV_PAGER]) return 1;    fclose(target);  rv = cmdftp_execute(env[CMDFTP_ENV_PAGER], 0, pipe_fd[0], -1);  close(pipe_fd[0]);  return rv;}/*****************************//* NETWORK RELATED FUNCTIONS *//*****************************/int cmdftp_connect(int port) {  struct sockaddr_in address; int s, opvalue; socklen_t slen;    opvalue = 8; slen = sizeof(opvalue);  memset(&address, 0, sizeof(address));  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||      setsockopt(s, IPPROTO_IP, IP_TOS, &opvalue, slen) < 0)    return 0;  address.sin_family = AF_INET;  address.sin_port = htons((unsigned short)port);  if (!server)    if (!(server = gethostbyname(o.hostname))) return 0;  memcpy(&address.sin_addr.s_addr, server->h_addr, server->h_length);    if (connect(s, (struct sockaddr*) &address, sizeof(address)) == -1)    return 0;  return s;}void cmdftp_reconnect(void) {  if (!(cmdftp_control = cmdftp_connect(o.p)))    cmdftp_err(CMDFTP_ERR_CONN, "");  greeting();  if (!logging_in) {    if (!login(user, pass)) cmdftp_err(CMDFTP_ERR_LGIN, "");    if (cwd[CMDFTP_LOCAL])      do_home(CMDFTP_LOCAL);    if (cwd[CMDFTP_REMOTE])      do_home(CMDFTP_REMOTE);  }}ssize_t my_raw_read(char* buf, size_t n, int sc) {   ssize_t rv;  rv = recv(sc, buf, n, 0);  if (rv < 0) {    if (transfer_interrupted != TRAN_INTR_INT)      transfer_interrupted = TRAN_INTR_PIPE;  }  return rv;}ssize_t my_raw_write(char* buf, size_t n, int sc) {  ssize_t rv;  rv = send(sc, buf, n, 0);  if (rv < 0) {    if (transfer_interrupted != TRAN_INTR_INT)      transfer_interrupted = TRAN_INTR_PIPE;  }  return rv;}int send_command(char* cmd, char suppress_err) {   char* s; size_t len, rv = 0;  s = my_malloc((len = strlen(cmd) + 2) + 1);  sprintf(s, "%s\r\n", cmd);

⌨️ 快捷键说明

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