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

📄 cmdftp.c

📁 ftp客户端程序
💻 C
📖 第 1 页 / 共 4 页
字号:
 start_transfer:  transfer_interrupted = TRAN_INTR_NO;  if (my_raw_write(s, len, cmdftp_control) < 0) {    s[len - 2] = 0;    if TRANSFER_INTERRUPTED_CHECK(s, 0);  } else {    s[len - 2] = 0;    if (!(rv = recv_answer(0, 0, suppress_err))) {      if TRANSFER_INTERRUPTED_CHECK(s, 1);    }  }  free(s);  return rv;}void reset_cmd_buffer(void) {  cmd_ptr = cmd_buffer + CMD_BUF_SIZE;}char* recv_line(int sc) {  char* new_ptr;  ptrdiff_t n; size_t len;  if (*cmd_ptr == 0) {    ssize_t bytes = my_raw_read(cmd_buffer, CMD_BUF_SIZE, sc);    if (bytes <= 0) return 0;    cmd_buffer[bytes] = 0;    cmd_ptr = cmd_buffer;    if (*cmd_ptr == '\n' && cmd_buffer[CMD_BUF_SIZE - 1] == '\r') cmd_ptr++;  }  new_ptr = strchr(cmd_ptr, '\r');  if (!new_ptr) new_ptr = cmd_buffer + CMD_BUF_SIZE;  n = new_ptr - cmd_ptr;  strncpy(cmd_line, cmd_ptr, n); cmd_line[n] = 0;  cmd_ptr = new_ptr;  if (cmd_ptr == cmd_buffer + CMD_BUF_SIZE) {    ssize_t bytes = my_raw_read(cmd_buffer, CMD_BUF_SIZE, sc);    if (bytes <= 0) return 0;    cmd_buffer[bytes] = 0;    cmd_ptr = cmd_buffer;    new_ptr = strchr(cmd_ptr, '\r');    if (!new_ptr) new_ptr = cmd_buffer + CMD_BUF_SIZE;            n = new_ptr - cmd_ptr; len = strlen(cmd_line);    strncat(cmd_line, cmd_ptr, n); cmd_line[len + n] = 0;    cmd_ptr = new_ptr;  }  if (*cmd_ptr == '\r') {    cmd_ptr++;    if (*cmd_ptr == '\n') cmd_ptr++;  }  return cmd_line;}int recv_confirm(void) {  int rv = 0; start_transfer:  if (recv_answer(0, 0, 0) == 226) rv = 1;  else if TRANSFER_INTERRUPTED_CHECK("recv_confirm", 1);  return rv;}int recv_answer(int store, struct line_data* d, char suppress_err) {  char* answer; int code; char str_code[] = { 0, 0, 0, ' ', 0 };  reset_cmd_buffer();  answer = recv_line(cmdftp_control);    if (!answer || strlen(answer) < 3) return 0;  strncpy(str_code, answer, 3);  if (answer[3] == '-') {    while ((answer = recv_line(cmdftp_control))) {             if (strncmp(answer, str_code, 4) == 0) break;      if (store) store_line(answer, d);      else printf("%s\n", answer);    }  }  sscanf(str_code, "%i", &code);  if (code >= 400 && !suppress_err) {    cmdftp_war(CMDFTP_WAR_RERR, answer);  }  return code;}int getport() {  unsigned int b[6];   int i, answer; size_t len; char* port_str;  if ((answer = send_command("PASV", 0)) != 227) return 0;  port_str = cmd_buffer + 4;  len = strlen(port_str += 4);  for (i = 0; i < len; i++)     if (!isdigit(port_str[i])) port_str[i] = ' ';    if (sscanf(port_str, "%u %u %u %u %u %u", b, b + 1, b + 2, b + 3, b + 4, b + 5) != 6) return 0;  return b[4] * 256 + b[5];}/*******************************//* MEMORY AND STRING FUNCTIONS *//*******************************/void* my_malloc(size_t s) {  void* rv;  if (!(rv = malloc(s))) cmdftp_err(CMDFTP_ERR_HEAP, "");  return rv;}void* my_realloc(void* ptr, size_t s) {  void* rv;  if (!(rv = realloc(ptr, s))) cmdftp_err(CMDFTP_ERR_HEAP, "");  return rv;}#if !HAVE_STRDUPchar* strdup(char* s) {  char* rv = malloc(strlen(s) + 1);  strcpy(rv, s);  return rv;}#endifchar* my_strdup(char* s) {  char* rv;  if (!(rv = strdup(s))) cmdftp_err(CMDFTP_ERR_HEAP, "");  return rv;}/***************************//* OTHER UTILITY FUNCTIONS *//***************************/void cleanexit(void) {  exit(fclose(stdout) == 0 ? 0 : -1);}void split_cmd(char* cmd, char** argv) {  size_t len; int i;  len = strlen(cmd);  for (i = 0; i < 4; i++) {    argv[i] = my_malloc(len + 1);    while (isspace(*cmd)) cmd++;    read_token(&cmd, argv[i]);  }}void free_cmd(char** argv) {  int i;  for (i = 0; i < 4; i++) {    if (argv[i]) {      free(argv[i]); argv[i] = 0;    }  }}  int str_binsearch(char* key) {  int low, high, mid, chk;  low = 0; high = N_COMMANDS - 1;  while (low <= high) {    mid = (low + high) / 2;    if ((chk = strcmp(key, commands[mid])) > 0) low = mid + 1;    else if (chk < 0) high = mid - 1;    else return mid;  }  return -1;}char* readline(int enable_tab, int enable_echo) {  char* ptr; int c;  ptr = cmd_userinput; memset(cmd_userinput, 0, sizeof(cmd_userinput));  cmdftp_raw_mode();    while (1) {    c = fgetc(stdin);    if (c == '\n')      { *ptr = 0; fputc('\n', stdout); break; }    else if ((c == '\t') && (enable_tab) &&	     (ptr - cmd_userinput) < (CMD_BUF_SIZE - 10))      { readline_tab(); ptr = cmd_userinput + strlen(cmd_userinput); }    else if (c == cmdftp_termios.c_cc[VERASE] || c == 8)      readline_bs(&ptr, enable_echo);    else if ((c >= 32) && (c <= 127)) {      if ((ptr - cmd_userinput) < (CMD_BUF_SIZE - 10))	{ *ptr++ = c; if (enable_echo) fputc(c, stdout); }    }    else if (c == EOF) break;  }  cmdftp_canon_mode();  return (c != EOF) ? my_strdup(cmd_userinput) : 0;}void readline_bs(char** ptr, int enable_echo) {  if (*ptr > cmd_userinput) {    *(--(*ptr)) = 0;    if (enable_echo) fprintf(stdout, "\b \b");  }}void readline_tab(void) {  char* argv[4];  char* mask, *completion; struct list_data ld;  int c, i, j, lc_mode; size_t len, len_buffer;  split_cmd(cmd_userinput, argv);  if (!*argv[1])    { free_cmd(argv); return; }  mask = 0;  c = i = j = len = len_buffer = 0;  init_list(&ld);  if (strcmp(argv[0], "d") == 0 || strcmp(argv[0], "dr") == 0) {    lc_mode = *argv[2] ? CMDFTP_LOCAL : CMDFTP_REMOTE;  } else if (strcmp(argv[0], "u") == 0) {    lc_mode = *argv[2] ? CMDFTP_REMOTE : CMDFTP_LOCAL;  } else lc_mode = mode;    if (*(mask = argv[2]) != '\0') {    char* tmp; tmp = escape_string(argv[1]);    free(argv[1]); argv[1] = tmp;  } else {    mask = argv[1];  }  strcat(mask, "*");  len_buffer = strlen(mask) - 1;    if (!mf[lc_mode][MODE_FETCH_LIST](mask, &ld) || ld.count == 0) goto endtab;  escape_list(&ld);  len = strlen(ld.data[0].escaped_fullname);    for (i = 0; i < len; i++) {    c = ld.data[0].escaped_fullname[i];    for (j = 1; j < ld.count; j++) {      if (ld.data[j].escaped_fullname[i] != c) goto endcommon;    }  }   endcommon: endtab:  if (ld.count) {    completion = my_malloc(i + 2);    strncpy(completion, ld.data[0].escaped_fullname, i);    if (ld.count == 1 &&	mf[lc_mode][MODE_FILE](ld.data[0].fullname) == FILE_ISDIR)      completion[i++] = '/';    completion[i] = 0;  } else {    completion = my_malloc(len_buffer + 1);    strncpy(completion, mask, len_buffer);    completion[len_buffer] = 0;  }    snprintf(cmd_userinput, CMD_BUF_SIZE, "%s%s%s%s%s", argv[0],	   *argv[1] ? " " : "", *argv[2] ? argv[1] : "", *argv[2] ? " " : "",	   completion);  free(completion);    if (ld.count > 1) {    fputc('\n', stdout);    for (j = 0; j < ld.count; j++) {      printf("%s\n", ld.data[j].escaped_fullname);    }  } else {    fputc('\r', stdout);  }  print_prompt(); printf("%s", cmd_userinput);  free_list(&ld);  free_cmd(argv);}void cmdftp_pwd_start(void) {  cmdftp_termios.c_lflag &= ~ECHO; tcsetattr(0, TCSANOW, &cmdftp_termios);}void cmdftp_pwd_end(void) {  cmdftp_termios.c_lflag |= ECHO; tcsetattr(0, TCSANOW, &cmdftp_termios);}void cmdftp_raw_mode(void) {  cmdftp_termios.c_lflag &= ~ICANON;  cmdftp_termios.c_lflag &= ~ECHO;  cmdftp_termios.c_cc[VMIN] = 1;  cmdftp_termios.c_cc[VTIME] = 0;  tcsetattr(0, TCSANOW, &cmdftp_termios);}void cmdftp_canon_mode(void) {  cmdftp_termios.c_lflag |= ICANON; cmdftp_termios.c_lflag |= ECHO;  tcsetattr(0, TCSANOW, &cmdftp_termios);}int cmdftp_execute(char* p1, char* p2, int read_fd, int write_fd) {  char** argv = 0; char* argptr;  pid_t pid; int status, rv, count;  rv = count = 0;  argptr = p1 = my_strdup(p1);  do {    argv = my_realloc(argv, sizeof(char*) * (count + 1));    argv[count++] = argptr;    argptr = strchr(argptr + 1, ' ');    if (argptr) *argptr++ = 0;  } while (argptr);  count += (p2 ? 2 : 1); argv = my_realloc(argv, sizeof(char*) * count);  argv[count - 1] = 0; if (p2) argv[count - 2] = p2;  if ((pid = fork()) < 0) goto end_proc;  else if (pid > 0) {    if (waitpid(pid, &status, 0) > 0) {      if (WIFEXITED(status) && (WEXITSTATUS(status) == 0)) rv = 1;    }  } else {    if (read_fd != -1) { close(0); dup(read_fd); close(read_fd); }    if (write_fd != -1) { close(1); dup(write_fd); close(write_fd); }    execvp(argv[0], argv);    exit(-1);  } end_proc:  free(p1); free(argv);  return rv;}/* temporary file handling */char* cmdftp_temp_fn;size_t cmdftp_temp_fn_len;int is_good_tmpdir(char* candidate) {  struct stat buf;  if (stat(candidate, &buf) != 0)    return 0;    return (S_ISDIR(buf.st_mode) && (buf.st_mode & S_IRWXU));}void init_temp(void) {  if (env[CMDFTP_ENV_TMPDIR] && is_good_tmpdir(env[CMDFTP_ENV_TMPDIR])) {    cmdftp_temp_fn = fullpath(env[CMDFTP_ENV_TMPDIR], "cmdftpXXXXXX");#ifdef P_tmpdir  } else if (is_good_tmpdir(P_tmpdir)) {    cmdftp_temp_fn = fullpath(P_tmpdir, "cmdftpXXXXXX");#endif  } else if (is_good_tmpdir("/tmp")) {    cmdftp_temp_fn = fullpath("/tmp", "cmdftpXXXXXX");  } else {    cmdftp_err(CMDFTP_ERR_TMPD, "");  }  cmdftp_temp_fn_len = strlen(cmdftp_temp_fn);}#if !HAVE_MKSTEMPint mkstemp(char* template) {#define MKSTEMP_ATTEMPTS 10  int rv, attempt; size_t len; char *ptr; off_t n;  char ascii[] =     "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";  len = strlen(template);	/* must be >= 6 */  ptr = template + len - 6;     /* point to XXXXXX part */  n = *((off_t*)o.hostname);	/* a crazy thing */  if (n < 0) n = -n;  for (attempt = 0; attempt < MKSTEMP_ATTEMPTS; attempt++) {    int i;    for (i = 0; i < 6; i++) {      ptr[i] = ascii[n % (sizeof(ascii) - 1)]; n /= sizeof(ascii) - 1;    }    rv = open(template, O_RDWR | O_CREAT | O_EXCL, 0600);    if (rv >= 0 || errno != EEXIST) return rv;  }  errno = EEXIST;  return -1;#undef MKSTEMP_ATTEMPTS}#endifFILE* cmdftp_temp(char** fn) {  int i; FILE* rv;  *fn = 0;  for (i = cmdftp_temp_fn_len - 6; i < cmdftp_temp_fn_len; i++)    cmdftp_temp_fn[i] = 'X';  if ((i = mkstemp(cmdftp_temp_fn)) < 0) return 0;  if (!(rv = fdopen(i, "r+"))) return 0;  *fn = my_strdup(cmdftp_temp_fn);  return rv;}void canonized_fn(char* des[3], char* arg) {  char* tmpmask;  tmpmask = my_strdup(arg);  des[0] = my_strdup(dirname(tmpmask));  free(tmpmask);  tmpmask = my_strdup(arg);  des[1] = my_strdup(basename(tmpmask));  free(tmpmask);  des[2] = fullpath(des[0], des[1]);}/*****************************************************************************/void free_fn(char* des[3]) {  int i;  for (i = 0; i < 3; i++) free(des[i]);}/*****************************************************************************/char* clean_fn(char* fn) {  if (strncmp(fn, "./", 2) == 0) return fn + 2;  else if(strncmp(fn, "//", 2) == 0) return fn + 1;  else return fn;}/*****************************************************************************/char* fullpath(char* s, char* q) {  char* rv = my_malloc(strlen(s) + strlen(q) + 2);  sprintf(rv, "%s/%s", s, q);  return rv;}/********************//* SIGNAL FUNCTIONS *//********************/void init_signals(void) {  memset(&sa, 0, sizeof(sa));  sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, 0);   sa.sa_handler = &handler_INT; sigaction(SIGINT, &sa, 0);}void handler_INT(int i) {   if (transfer_interrupted == TRAN_INTR_INT) {    cmdftp_err(CMDFTP_ERR_INTR, "");  } else {    transfer_interrupted = TRAN_INTR_INT;  }}/******************************//* STRUCT LINE_DATA FUNCTIONS *//******************************/void init_lines(struct line_data* d) {  d->count = 0; d->lines = 0;}void init_list(struct list_data* d) {  d->count = 0; d->data = 0;}void escape_list(struct list_data* d) {  int i;  for (i = 0; i < d->count; i++) {    d->data[i].escaped_fullname =      escape_string(d->data[i].fullname);  }}char* escape_string(char* filestring) {  char* src, *dst, *fs_new;  size_t len;  len = strlen(src = filestring);  dst = fs_new = my_malloc(len * 2 + 1);  do {    if (*src == '\\') {      *dst++ = '\\';    } else if (*src == ' ') {      *dst++ = '\\';    }  } while ((*dst++ = *src++));  return fs_new;}void store_line(char* line, struct line_data* d) {  int i = d->count;  d->lines = my_realloc(d->lines, sizeof(char*) * (++d->count));  d->lines[i] = my_malloc(CMD_BUF_SIZE - 9);  strncpy(d->lines[i], line, CMD_BUF_SIZE - 10);  d->lines[i][CMD_BUF_SIZE - 10] = 0; }void store_list(char* fullname, struct list_data* d) {  int i; char* base;  base = basename(fullname);  if ((o.d && (strcmp(base, ".") == 0 || strcmp(base, "..") == 0)) ||      (!o.d && *base == '.')) return;    i = d->count;  d->data = my_realloc(d->data, sizeof(struct list_entry) * (++d->count));  d->data[i].escaped_fullname = 0;  d->data[i].fullname = my_strdup(fullname);  d->data[i].basename = my_strdup(base);  d->data[i].dirname = my_strdup(dirname(fullname));}void store_pretty_list(char* fullname, struct list_data* d) {  int i = d->count;  d->data = my_realloc(d->data, sizeof(struct list_entry) * (++d->count));  d->data[i].escaped_fullname = 0;  d->data[i].fullname = my_strdup(fullname);  d->data[i].basename = d->data[i].dirname = 0;}void free_lines(struct line_data* d) {  int i;  if (d->lines) {    for (i = 0; i < d->count; i++) free(d->lines[i]);    free(d->lines); d->lines = 0;  }   d->count = 0;}void free_list(struct list_data* d) {  int i;  if (d->data) {    for (i = 0; i < d->count; i++) {      if (d->data[i].escaped_fullname) free(d->data[i].escaped_fullname);      if (d->data[i].fullname) free(d->data[i].fullname);      if (d->data[i].basename) free(d->data[i].basename);      if (d->data[i].dirname) free(d->data[i].dirname);    }    free(d->data); d->data = 0;  }  d->count = 0;}

⌨️ 快捷键说明

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