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

📄 sysdeputil.c

📁 文件传输协议linux 下vsftpd2.1.0.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
{  /* Grr - why is off_t signed? */  if (*p_offset < 0 || num_send < 0)  {    die("invalid offset or send count in vsf_sysutil_sendfile");  }  if (max_chunk == 0)  {    max_chunk = INT_MAX;  }  while (num_send > 0)  {    int retval;    unsigned int send_this_time;    if (num_send > max_chunk)    {      send_this_time = max_chunk;    }    else    {      send_this_time = (unsigned int) num_send;    }    /* Keep input file position in line with sendfile() calls */    vsf_sysutil_lseek_to(in_fd, *p_offset);    retval = do_sendfile(out_fd, in_fd, send_this_time, *p_offset);    if (vsf_sysutil_retval_is_error(retval) || retval == 0)    {      return retval;    }    num_send -= retval;    *p_offset += retval;  }  return 0;}static int do_sendfile(const int out_fd, const int in_fd,                       unsigned int num_send, filesize_t start_pos){  /* Probably should one day be shared with instance in ftpdataio.c */  static char* p_recvbuf;  unsigned int total_written = 0;  int retval;  enum EVSFSysUtilError error;  (void) start_pos;  (void) error;#if defined(VSF_SYSDEP_HAVE_LINUX_SENDFILE) || \    defined(VSF_SYSDEP_HAVE_FREEBSD_SENDFILE) || \    defined(VSF_SYSDEP_HAVE_HPUX_SENDFILE) || \    defined(VSF_SYSDEP_HAVE_AIX_SENDFILE) || \    defined(VSF_SYSDEP_HAVE_SOLARIS_SENDFILE)  if (tunable_use_sendfile)  {    static int s_sendfile_checked;    static int s_runtime_sendfile_works;    if (!s_sendfile_checked || s_runtime_sendfile_works)    {      do      {  #ifdef VSF_SYSDEP_HAVE_LINUX_SENDFILE        retval = sendfile(out_fd, in_fd, NULL, num_send);  #elif defined(VSF_SYSDEP_HAVE_FREEBSD_SENDFILE)        {          /* XXX - start_pos will truncate on 32-bit machines - can we           * say "start from current pos"?           */          off_t written = 0;          retval = sendfile(in_fd, out_fd, start_pos, num_send, NULL,                            &written, 0);          /* Translate to Linux-like retval */          if (written > 0)          {            retval = (int) written;          }        }  #elif defined(VSF_SYSDEP_HAVE_SOLARIS_SENDFILE)        {          size_t written = 0;          struct sendfilevec the_vec;          vsf_sysutil_memclr(&the_vec, sizeof(the_vec));          the_vec.sfv_fd = in_fd;          the_vec.sfv_off = start_pos;          the_vec.sfv_len = num_send;          retval = sendfilev(out_fd, &the_vec, 1, &written);          /* Translate to Linux-like retval */          if (written > 0)          {            retval = (int) written;          }        }  #elif defined(VSF_SYSDEP_HAVE_AIX_SENDFILE)        {          struct sf_parms sf_iobuf;          vsf_sysutil_memclr(&sf_iobuf, sizeof(sf_iobuf));          sf_iobuf.header_data = NULL;          sf_iobuf.header_length = 0;          sf_iobuf.trailer_data = NULL;          sf_iobuf.trailer_length = 0;          sf_iobuf.file_descriptor = in_fd;          sf_iobuf.file_offset = start_pos;          sf_iobuf.file_bytes = num_send;          retval = send_file((int*)&out_fd, &sf_iobuf, 0);          if (retval >= 0)          {            retval = sf_iobuf.bytes_sent;          }        }  #else /* must be VSF_SYSDEP_HAVE_HPUX_SENDFILE */        {          retval = sendfile(out_fd, in_fd, start_pos, num_send, NULL, 0);        }  #endif /* VSF_SYSDEP_HAVE_LINUX_SENDFILE */        error = vsf_sysutil_get_error();        vsf_sysutil_check_pending_actions(kVSFSysUtilIO, retval, out_fd);      }      while (vsf_sysutil_retval_is_error(retval) &&             error == kVSFSysUtilErrINTR);      if (!s_sendfile_checked)      {        s_sendfile_checked = 1;        if (!vsf_sysutil_retval_is_error(retval) ||            error != kVSFSysUtilErrNOSYS)        {          s_runtime_sendfile_works = 1;        }      }      if (!vsf_sysutil_retval_is_error(retval))      {        return retval;      }      if (s_runtime_sendfile_works && error != kVSFSysUtilErrINVAL &&          error != kVSFSysUtilErrOPNOTSUPP)      {        return retval;      }      /* Fall thru to normal implementation. We won't check again. NOTE -       * also falls through if sendfile() is OK but it returns EINVAL. For       * Linux this means the file was not page cache backed. Original       * complaint was trying to serve files from an NTFS filesystem!       */    }  }#endif /* VSF_SYSDEP_HAVE_LINUX_SENDFILE || VSF_SYSDEP_HAVE_FREEBSD_SENDFILE */  if (p_recvbuf == 0)  {    vsf_secbuf_alloc(&p_recvbuf, VSFTP_DATA_BUFSIZE);  }  while (1)  {    unsigned int num_read;    unsigned int num_written;    unsigned int num_read_this_time = VSFTP_DATA_BUFSIZE;    if (num_read_this_time > num_send)    {      num_read_this_time = num_send;    }    retval = vsf_sysutil_read(in_fd, p_recvbuf, num_read_this_time);    if (retval < 0)    {      return retval;    }    else if (retval == 0)    {      return -1;    }    num_read = (unsigned int) retval;    retval = vsf_sysutil_write_loop(out_fd, p_recvbuf, num_read);    if (retval < 0)    {      return retval;    }    num_written = (unsigned int) retval;    total_written += num_written;    if (num_written != num_read)    {      return num_written;    }    if (num_written > num_send)    {      bug("num_written bigger than num_send in do_sendfile");    }    num_send -= num_written;    if (num_send == 0)    {      /* Bingo! */      return total_written;    }  }}voidvsf_sysutil_set_proctitle_prefix(const struct mystr* p_str){  str_copy(&s_proctitle_prefix_str, p_str);}/* This delegation is common to all setproctitle() implementations */voidvsf_sysutil_setproctitle_str(const struct mystr* p_str){  vsf_sysutil_setproctitle(str_getbuf(p_str));}voidvsf_sysutil_setproctitle(const char* p_text){  struct mystr proctitle_str = INIT_MYSTR;  str_copy(&proctitle_str, &s_proctitle_prefix_str);  if (!str_isempty(&proctitle_str))  {    str_append_text(&proctitle_str, ": ");  }  str_append_text(&proctitle_str, p_text);  vsf_sysutil_setproctitle_internal(str_getbuf(&proctitle_str));  str_free(&proctitle_str);}#ifdef VSF_SYSDEP_HAVE_SETPROCTITLEvoidvsf_sysutil_setproctitle_init(int argc, const char* argv[]){  (void) argc;  (void) argv;}voidvsf_sysutil_setproctitle_internal(const char* p_buf){  setproctitle("%s", p_buf);}#elif defined(VSF_SYSDEP_HAVE_HPUX_SETPROCTITLE)voidvsf_sysutil_setproctitle_init(int argc, const char* argv[]){  (void) argc;  (void) argv;}voidvsf_sysutil_setproctitle_internal(const char* p_buf){  struct mystr proctitle_str = INIT_MYSTR;  union pstun p;  str_alloc_text(&proctitle_str, "vsftpd: ");  str_append_text(&proctitle_str, p_buf);  p.pst_command = str_getbuf(&proctitle_str);  pstat(PSTAT_SETCMD, p, 0, 0, 0);  str_free(&proctitle_str);}#elif defined(VSF_SYSDEP_TRY_LINUX_SETPROCTITLE_HACK)voidvsf_sysutil_setproctitle_init(int argc, const char* argv[]){  int i;  char** p_env = environ;  if (s_proctitle_inited)  {    bug("vsf_sysutil_setproctitle_init called twice");  }  s_proctitle_inited = 1;  if (argv[0] == 0)  {    die("no argv[0] in vsf_sysutil_setproctitle_init");  }  for (i=0; i<argc; i++)  {    s_proctitle_space += vsf_sysutil_strlen(argv[i]) + 1;    if (i > 0)    {      argv[i] = 0;    }  }  while (*p_env != 0)  {    s_proctitle_space += vsf_sysutil_strlen(*p_env) + 1;    p_env++;  }  /* Oops :-) */  environ = 0;  s_p_proctitle = (char*) argv[0];  vsf_sysutil_memclr(s_p_proctitle, s_proctitle_space);}voidvsf_sysutil_setproctitle_internal(const char* p_buf){  struct mystr proctitle_str = INIT_MYSTR;  unsigned int to_copy;  if (!s_proctitle_inited)  {    bug("vsf_sysutil_setproctitle: not initialized");  }  vsf_sysutil_memclr(s_p_proctitle, s_proctitle_space);  if (s_proctitle_space < 32)  {    return;  }  str_alloc_text(&proctitle_str, "vsftpd: ");  str_append_text(&proctitle_str, p_buf);  to_copy = str_getlen(&proctitle_str);  if (to_copy > s_proctitle_space - 1)  {    to_copy = s_proctitle_space - 1;  }  vsf_sysutil_memcpy(s_p_proctitle, str_getbuf(&proctitle_str), to_copy);  str_free(&proctitle_str);  s_p_proctitle[to_copy] = '\0';}#else /* VSF_SYSDEP_HAVE_SETPROCTITLE */voidvsf_sysutil_setproctitle_init(int argc, const char* argv[]){  (void) argc;  (void) argv;}voidvsf_sysutil_setproctitle_internal(const char* p_buf){  (void) p_buf;}#endif /* VSF_SYSDEP_HAVE_SETPROCTITLE */#ifdef VSF_SYSDEP_HAVE_MAP_ANONvoidvsf_sysutil_map_anon_pages_init(void){}void*vsf_sysutil_map_anon_pages(unsigned int length){  char* retval = mmap(0, length, PROT_READ | PROT_WRITE,                      MAP_PRIVATE | MAP_ANON, -1, 0);  if (retval == MAP_FAILED)  {    die("mmap");  }  return retval;}#else /* VSF_SYSDEP_HAVE_MAP_ANON */voidvsf_sysutil_map_anon_pages_init(void){  if (s_zero_fd != -1)  {    bug("vsf_sysutil_map_anon_pages_init called twice");  }  s_zero_fd = open("/dev/zero", O_RDWR);  if (s_zero_fd < 0)  {    die("could not open /dev/zero");  }}void*vsf_sysutil_map_anon_pages(unsigned int length){  char* retval = mmap(0, length, PROT_READ | PROT_WRITE,                      MAP_PRIVATE, s_zero_fd, 0);  if (retval == MAP_FAILED)  {    die("mmap");  }  return retval;}#endif /* VSF_SYSDEP_HAVE_MAP_ANON */#ifndef VSF_SYSDEP_NEED_OLD_FD_PASSINGvoidvsf_sysutil_send_fd(int sock_fd, int send_fd){  int retval;  struct msghdr msg;  struct cmsghdr* p_cmsg;  struct iovec vec;  char cmsgbuf[CMSG_SPACE(sizeof(send_fd))];  int* p_fds;  char sendchar = 0;  msg.msg_control = cmsgbuf;  msg.msg_controllen = sizeof(cmsgbuf);  p_cmsg = CMSG_FIRSTHDR(&msg);  p_cmsg->cmsg_level = SOL_SOCKET;  p_cmsg->cmsg_type = SCM_RIGHTS;  p_cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));  p_fds = (int*)CMSG_DATA(p_cmsg);  *p_fds = send_fd;  msg.msg_controllen = p_cmsg->cmsg_len;  msg.msg_name = NULL;  msg.msg_namelen = 0;  msg.msg_iov = &vec;  msg.msg_iovlen = 1;  msg.msg_flags = 0;  /* "To pass file descriptors or credentials you need to send/read at   * least on byte" (man 7 unix)   */  vec.iov_base = &sendchar;  vec.iov_len = sizeof(sendchar);  retval = sendmsg(sock_fd, &msg, 0);  if (retval != 1)  {    die("sendmsg");  }}intvsf_sysutil_recv_fd(const int sock_fd){  int retval;  struct msghdr msg;  char recvchar;  struct iovec vec;  int recv_fd;  char cmsgbuf[CMSG_SPACE(sizeof(recv_fd))];  struct cmsghdr* p_cmsg;  int* p_fd;  vec.iov_base = &recvchar;  vec.iov_len = sizeof(recvchar);  msg.msg_name = NULL;  msg.msg_namelen = 0;  msg.msg_iov = &vec;  msg.msg_iovlen = 1;  msg.msg_control = cmsgbuf;  msg.msg_controllen = sizeof(cmsgbuf);  msg.msg_flags = 0;  /* In case something goes wrong, set the fd to -1 before the syscall */  p_fd = (int*)CMSG_DATA(CMSG_FIRSTHDR(&msg));  *p_fd = -1;    retval = recvmsg(sock_fd, &msg, 0);  if (retval != 1)  {    die("recvmsg");  }  p_cmsg = CMSG_FIRSTHDR(&msg);  if (p_cmsg == NULL)  {    die("no passed fd");  }  /* We used to verify the returned cmsg_level, cmsg_type and cmsg_len here,   * but Linux 2.0 totally uselessly fails to fill these in.   */  p_fd = (int*)CMSG_DATA(p_cmsg);  recv_fd = *p_fd;  if (recv_fd == -1)  {    die("no passed fd");  }  return recv_fd;}#else /* !VSF_SYSDEP_NEED_OLD_FD_PASSING */voidvsf_sysutil_send_fd(int sock_fd, int send_fd){  int retval;  char send_char = 0;  struct msghdr msg;  struct iovec vec;  vec.iov_base = &send_char;  vec.iov_len = 1;  msg.msg_name = NULL;  msg.msg_namelen = 0;  msg.msg_iov = &vec;  msg.msg_iovlen = 1;  msg.msg_accrights = (caddr_t) &send_fd;  msg.msg_accrightslen = sizeof(send_fd);  retval = sendmsg(sock_fd, &msg, 0);  if (retval != 1)  {    die("sendmsg");  }}intvsf_sysutil_recv_fd(int sock_fd){  int retval;  struct msghdr msg;  struct iovec vec;  char recv_char;  int recv_fd = -1;  vec.iov_base = &recv_char;  vec.iov_len = 1;  msg.msg_name = NULL;  msg.msg_namelen = 0;  msg.msg_iov = &vec;  msg.msg_iovlen = 1;  msg.msg_accrights = (caddr_t) &recv_fd;  msg.msg_accrightslen = sizeof(recv_fd);  retval = recvmsg(sock_fd, &msg, 0);  if (retval != 1)  {    die("recvmsg");  }  if (recv_fd == -1)  {    die("no passed fd");  }  return recv_fd;}#endif /* !VSF_SYSDEP_NEED_OLD_FD_PASSING */#ifndef VSF_SYSDEP_HAVE_UTMPXvoidvsf_insert_uwtmp(const struct mystr* p_user_str,                 const struct mystr* p_host_str){  (void) p_user_str;  (void) p_host_str;}voidvsf_remove_uwtmp(void){}#else /* !VSF_SYSDEP_HAVE_UTMPX *//* IMHO, the pam_unix module REALLY should be doing this in its SM component *//* Statics */static int s_uwtmp_inserted;static struct utmpx s_utent;voidvsf_insert_uwtmp(const struct mystr* p_user_str,                 const struct mystr* p_host_str){  if (sizeof(s_utent.ut_line) < 16)  {    return;  }  if (s_uwtmp_inserted)  {    bug("vsf_insert_uwtmp");  }  {    struct mystr line_str = INIT_MYSTR;    str_alloc_text(&line_str, "vsftpd:");    str_append_ulong(&line_str, vsf_sysutil_getpid());    if (str_getlen(&line_str) >= sizeof(s_utent.ut_line))    {      str_free(&line_str);      return;    }    vsf_sysutil_strcpy(s_utent.ut_line, str_getbuf(&line_str),                       sizeof(s_utent.ut_line));    str_free(&line_str);  }  s_uwtmp_inserted = 1;  s_utent.ut_type = USER_PROCESS;  s_utent.ut_pid = vsf_sysutil_getpid();  vsf_sysutil_strcpy(s_utent.ut_user, str_getbuf(p_user_str),                     sizeof(s_utent.ut_user));  vsf_sysutil_strcpy(s_utent.ut_host, str_getbuf(p_host_str),                     sizeof(s_utent.ut_host));  vsf_sysutil_update_cached_time();  s_utent.ut_tv.tv_sec = vsf_sysutil_get_cached_time_sec();  setutxent();  (void) pututxline(&s_utent);  endutxent();  updwtmpx(WTMPX_FILE, &s_utent);}voidvsf_remove_uwtmp(void){  if (!s_uwtmp_inserted)  {    return;  }  s_uwtmp_inserted = 0;  s_utent.ut_type = DEAD_PROCESS;  vsf_sysutil_memclr(s_utent.ut_user, sizeof(s_utent.ut_user));  vsf_sysutil_memclr(s_utent.ut_host, sizeof(s_utent.ut_host));  s_utent.ut_tv.tv_sec = 0;  setutxent();  (void) pututxline(&s_utent);  endutxent();  vsf_sysutil_update_cached_time();  s_utent.ut_tv.tv_sec = vsf_sysutil_get_cached_time_sec();  updwtmpx(WTMPX_FILE, &s_utent);}#endif /* !VSF_SYSDEP_HAVE_UTMPX */voidvsf_set_die_if_parent_dies(){#ifdef VSF_SYSDEP_HAVE_SETPDEATHSIG  if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0) != 0)  {    die("prctl");  }#endif}voidvsf_set_term_if_parent_dies(){#ifdef VSF_SYSDEP_HAVE_SETPDEATHSIG  if (prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0) != 0)  {    die("prctl");  }#endif}

⌨️ 快捷键说明

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