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

📄 sysutil.c

📁 linux下的轻量级的ftp服务器
💻 C
📖 第 1 页 / 共 4 页
字号:
  long local_time = vsf_sysutil_get_cached_time_sec();  const char* p_date_format = "%b %d %H:%M";  if (!use_localtime)  {    p_tm = gmtime(&p_stat->st_mtime);  }  else  {    p_tm = localtime(&p_stat->st_mtime);  }  /* Is this a future or 6 months old date? If so, we drop to year format */  if (p_stat->st_mtime > local_time ||      (local_time - p_stat->st_mtime) > 60*60*24*182)  {    p_date_format = "%b %d  %Y";  }  retval = strftime(datebuf, sizeof(datebuf), p_date_format, p_tm);  datebuf[sizeof(datebuf)-1] = '\0';  if (retval == 0)  {    die("strftime");  }  return datebuf;}const char*vsf_sysutil_statbuf_get_numeric_date(  const struct vsf_sysutil_statbuf* p_statbuf,  int use_localtime){  static char datebuf[15];  const struct stat* p_stat = (const struct stat*) p_statbuf;  struct tm* p_tm;  int retval;  if (!use_localtime)  {    p_tm = gmtime(&p_stat->st_mtime);  }  else  {    p_tm = localtime(&p_stat->st_mtime);  }  retval = strftime(datebuf, sizeof(datebuf), "%Y%m%d%H%M%S", p_tm);  if (retval == 0)  {    die("strftime");  }  return datebuf;}filesize_tvsf_sysutil_statbuf_get_size(const struct vsf_sysutil_statbuf* p_statbuf){  const struct stat* p_stat = (const struct stat*) p_statbuf;  if (p_stat->st_size < 0)  {    die("invalid inode size in vsf_sysutil_statbuf_get_size");  }  return p_stat->st_size;}intvsf_sysutil_statbuf_get_uid(const struct vsf_sysutil_statbuf* p_statbuf){  const struct stat* p_stat = (const struct stat*) p_statbuf;  return p_stat->st_uid;}intvsf_sysutil_statbuf_get_gid(const struct vsf_sysutil_statbuf* p_statbuf){  const struct stat* p_stat = (const struct stat*) p_statbuf;  return p_stat->st_gid;}unsigned intvsf_sysutil_statbuf_get_links(const struct vsf_sysutil_statbuf* p_statbuf){  const struct stat* p_stat = (const struct stat*) p_statbuf;  return p_stat->st_nlink;}intvsf_sysutil_statbuf_is_readable_other(  const struct vsf_sysutil_statbuf* p_statbuf){  const struct stat* p_stat = (const struct stat*) p_statbuf;  if (p_stat->st_mode & S_IROTH)  {    return 1;  }  return 0;}const char*vsf_sysutil_statbuf_get_sortkey_mtime(  const struct vsf_sysutil_statbuf* p_statbuf){  static char intbuf[32];  const struct stat* p_stat = (const struct stat*) p_statbuf;  /* This slight hack function must return a character date format such that   * more recent dates appear later in the alphabet! Most notably, we must   * make sure we pad to the same length with 0's    */  snprintf(intbuf, sizeof(intbuf), "%030ld", (long) p_stat->st_mtime);  return intbuf;}voidvsf_sysutil_fchown(const int fd, const int uid, const int gid){  if (fchown(fd, uid, gid) != 0)  {    die("fchown");  }}voidvsf_sysutil_fchmod(const int fd, unsigned int mode){  mode = mode & 0777;  if (fchmod(fd, mode))  {    die("fchmod");  }}intvsf_sysutil_chmod(const char* p_filename, unsigned int mode){  /* Safety: mask "mode" to just access permissions, e.g. no suid setting! */  mode = mode & 0777;  return chmod(p_filename, mode);}intvsf_sysutil_lock_file_write(int fd){  return lock_internal(fd, F_WRLCK);}intvsf_sysutil_lock_file_read(int fd){  return lock_internal(fd, F_RDLCK);}static intlock_internal(int fd, int lock_type){  struct flock the_lock;  int retval;  int saved_errno;  vsf_sysutil_memclr(&the_lock, sizeof(the_lock));  the_lock.l_type = lock_type;  the_lock.l_whence = SEEK_SET;  the_lock.l_start = 0;  the_lock.l_len = 0;  do  {    retval = fcntl(fd, F_SETLKW, &the_lock);    saved_errno = errno;    vsf_sysutil_check_pending_actions(kVSFSysUtilUnknown, 0, 0);  }  while (retval < 0 && saved_errno == EINTR);  return retval;}voidvsf_sysutil_unlock_file(int fd){  int retval;  struct flock the_lock;  vsf_sysutil_memclr(&the_lock, sizeof(the_lock));  the_lock.l_type = F_UNLCK;  the_lock.l_whence = SEEK_SET;  the_lock.l_start = 0;  the_lock.l_len = 0;  retval = fcntl(fd, F_SETLK, &the_lock);  if (retval != 0)  {    die("fcntl");  }}intvsf_sysutil_readlink(const char* p_filename, char* p_dest, unsigned int bufsiz){  int retval;  if (bufsiz == 0) {    return -1;  }  retval = readlink(p_filename, p_dest, bufsiz - 1);  if (retval < 0)  {    return retval;  }  /* Ensure buffer is NULL terminated; readlink(2) doesn't do that */  p_dest[retval] = '\0';  return retval;}intvsf_sysutil_retval_is_error(int retval){  if (retval < 0)  {    return 1;  }  return 0;}enum EVSFSysUtilErrorvsf_sysutil_get_error(void){  enum EVSFSysUtilError retval = kVSFSysUtilErrUnknown;  switch (errno)  {    case EADDRINUSE:      retval = kVSFSysUtilErrADDRINUSE;      break;    case ENOSYS:      retval = kVSFSysUtilErrNOSYS;      break;    case EINTR:      retval = kVSFSysUtilErrINTR;      break;    case EINVAL:      retval = kVSFSysUtilErrINVAL;      break;    case EOPNOTSUPP:      retval = kVSFSysUtilErrOPNOTSUPP;      break;  }  return retval;}intvsf_sysutil_get_ipv4_sock(void){  int retval = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);  if (retval < 0)  {    die("socket");  }  return retval;}intvsf_sysutil_get_ipv6_sock(void){  int retval = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);  if (retval < 0)  {    die("socket");  }  return retval;}struct vsf_sysutil_socketpair_retvalvsf_sysutil_unix_stream_socketpair(void){  struct vsf_sysutil_socketpair_retval retval;  int the_sockets[2];  int sys_retval = socketpair(PF_UNIX, SOCK_STREAM, 0, the_sockets);  if (sys_retval != 0)  {    die("socketpair");  }  retval.socket_one = the_sockets[0];  retval.socket_two = the_sockets[1];  return retval;}intvsf_sysutil_bind(int fd, const struct vsf_sysutil_sockaddr* p_sockptr){  const struct sockaddr* p_sockaddr = &p_sockptr->u.u_sockaddr;  int len = 0;  if (p_sockaddr->sa_family == AF_INET)  {    len = sizeof(struct sockaddr_in);  }  else if (p_sockaddr->sa_family == AF_INET6)  {    len = sizeof(struct sockaddr_in6);  }  else  {    die("can only support ipv4 and ipv6 currently");  }  return bind(fd, p_sockaddr, len);}intvsf_sysutil_listen(int fd, const unsigned int backlog){  int retval = listen(fd, backlog);  if (vsf_sysutil_retval_is_error(retval) &&      vsf_sysutil_get_error() != kVSFSysUtilErrADDRINUSE)  {    die("listen");  }  return retval;}/* Warning: callers of this function assume it does NOT make use of any * non re-entrant calls such as malloc(). */intvsf_sysutil_accept_timeout(int fd, struct vsf_sysutil_sockaddr* p_sockaddr,                           unsigned int wait_seconds){  struct vsf_sysutil_sockaddr remote_addr;  int retval;  int saved_errno;  fd_set accept_fdset;  struct timeval timeout;  unsigned int socklen = sizeof(remote_addr);  if (p_sockaddr)  {    vsf_sysutil_memclr(p_sockaddr, sizeof(*p_sockaddr));  }  if (wait_seconds > 0)  {    FD_ZERO(&accept_fdset);    FD_SET(fd, &accept_fdset);    timeout.tv_sec = wait_seconds;    timeout.tv_usec = 0;    do    {      retval = select(fd + 1, &accept_fdset, NULL, NULL, &timeout);      saved_errno = errno;      vsf_sysutil_check_pending_actions(kVSFSysUtilUnknown, 0, 0);    } while (retval < 0 && saved_errno == EINTR);    if (retval == 0)    {      errno = EAGAIN;      return -1;    }  }  retval = accept(fd, &remote_addr.u.u_sockaddr, &socklen);  vsf_sysutil_check_pending_actions(kVSFSysUtilUnknown, 0, 0);  if (retval < 0)  {    return retval;  }  /* FreeBSD bug / paranoia: ai32@drexel.edu */  if (socklen == 0)  {    return -1;  }  if (remote_addr.u.u_sockaddr.sa_family != AF_INET &&      remote_addr.u.u_sockaddr.sa_family != AF_INET6)  {    die("can only support ipv4 and ipv6 currently");  }  if (p_sockaddr)  {    if (remote_addr.u.u_sockaddr.sa_family == AF_INET)    {      vsf_sysutil_memclr(&remote_addr.u.u_sockaddr_in.sin_zero,                         sizeof(remote_addr.u.u_sockaddr_in.sin_zero));      vsf_sysutil_memcpy(p_sockaddr, &remote_addr.u.u_sockaddr_in,                         sizeof(remote_addr.u.u_sockaddr_in));    }    else    {      vsf_sysutil_memcpy(p_sockaddr, &remote_addr.u.u_sockaddr_in6,                         sizeof(remote_addr.u.u_sockaddr_in6));    }  }  return retval;}intvsf_sysutil_connect_timeout(int fd, const struct vsf_sysutil_sockaddr* p_addr,                            unsigned int wait_seconds){  const struct sockaddr* p_sockaddr = &p_addr->u.u_sockaddr;  unsigned int addrlen = 0;  int retval;  int saved_errno;  if (p_sockaddr->sa_family == AF_INET)  {    addrlen = sizeof(p_addr->u.u_sockaddr_in);  }  else if (p_sockaddr->sa_family == AF_INET6)  {    addrlen = sizeof(p_addr->u.u_sockaddr_in6);  }  else  {    die("can only support ipv4 and ipv6 currently");  }  if (wait_seconds > 0)  {    vsf_sysutil_activate_noblock(fd);  }  retval = connect(fd, p_sockaddr, addrlen);  if (retval < 0 && errno == EINPROGRESS)  {    fd_set connect_fdset;    struct timeval timeout;    FD_ZERO(&connect_fdset);    FD_SET(fd, &connect_fdset);    timeout.tv_sec = wait_seconds;    timeout.tv_usec = 0;    do    {      retval = select(fd + 1, NULL, &connect_fdset, NULL, &timeout);      saved_errno = errno;      vsf_sysutil_check_pending_actions(kVSFSysUtilUnknown, 0, 0);    }    while (retval < 0 && saved_errno == EINTR);    if (retval == 0)    {      retval = -1;      errno = EAGAIN;    }    else    {      socklen_t socklen = sizeof(retval);      int sockoptret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &retval, &socklen);      if (sockoptret != 0)      {        die("getsockopt");      }    }  }  if (wait_seconds > 0)  {    vsf_sysutil_deactivate_noblock(fd);  }  return retval;}voidvsf_sysutil_getsockname(int fd, struct vsf_sysutil_sockaddr** p_sockptr){  struct vsf_sysutil_sockaddr the_addr;  int retval;  unsigned int socklen = sizeof(the_addr);  vsf_sysutil_sockaddr_clear(p_sockptr);  retval = getsockname(fd, &the_addr.u.u_sockaddr, &socklen);  if (retval != 0)  {    die("getsockname");  }  if (the_addr.u.u_sockaddr.sa_family != AF_INET &&      the_addr.u.u_sockaddr.sa_family != AF_INET6)  {    die("can only support ipv4 and ipv6 currently");  }  vsf_sysutil_sockaddr_alloc(p_sockptr);  if (socklen > sizeof(the_addr))  {    socklen = sizeof(the_addr);  }  vsf_sysutil_memcpy(*p_sockptr, &the_addr, socklen);}voidvsf_sysutil_getpeername(int fd, struct vsf_sysutil_sockaddr** p_sockptr){  struct vsf_sysutil_sockaddr the_addr;  int retval;  unsigned int socklen = sizeof(the_addr);  vsf_sysutil_sockaddr_clear(p_sockptr);  retval = getpeername(fd, &the_addr.u.u_sockaddr, &socklen);  if (retval != 0)  {    die("getpeername");  }  if (the_addr.u.u_sockaddr.sa_family != AF_INET &&      the_addr.u.u_sockaddr.sa_family != AF_INET6)  {    die("can only support ipv4 and ipv6 currently");  }  vsf_sysutil_sockaddr_alloc(p_sockptr);  if (socklen > sizeof(the_addr))  {    socklen = sizeof(the_addr);  }  vsf_sysutil_memcpy(*p_sockptr, &the_addr, socklen);}voidvsf_sysutil_shutdown_failok(int fd){  /* SHUT_RDWR is a relatively new addition */  #ifndef SHUT_RDWR  #define SHUT_RDWR 2  #endif  (void) shutdown(fd, SHUT_RDWR);}voidvsf_sysutil_shutdown_read_failok(int fd){  /* SHUT_RD is a relatively new addition */  #ifndef SHUT_RD  #define SHUT_RD 0  #endif  (void) shutdown(fd, SHUT_RD);}voidvsf_sysutil_sockaddr_clear(struct vsf_sysutil_sockaddr** p_sockptr){  if (*p_sockptr != NULL)  {    vsf_sysutil_free(*p_sockptr);    *p_sockptr = NULL;  }}voidvsf_sysutil_sockaddr_alloc(struct vsf_sysutil_sockaddr** p_sockptr){  vsf_sysutil_sockaddr_clear(p_sockptr);  *p_sockptr = vsf_sysutil_malloc(sizeof(**p_sockptr));  vsf_sysutil_memclr(*p_sockptr, sizeof(**p_sockptr));}voidvsf_sysutil_sockaddr_alloc_ipv4(struct vsf_sysutil_sockaddr** p_sockptr){  vsf_sysutil_sockaddr_alloc(p_sockptr);  (*p_sockptr)->u.u_sockaddr.sa_family = AF_INET;}voidvsf_sysutil_sockaddr_alloc_ipv6(struct vsf_sysutil_sockaddr** p_sockptr){  vsf_sysutil_sockaddr_alloc(p_sockptr);  (*p_sockptr)->u.u_sockaddr.sa_family = AF_INET6;}voidvsf_sysutil_sockaddr_clone(struct vsf_sysutil_sockaddr** p_sockptr,                           const struct vsf_sysutil_sockaddr* p_src){  struct vsf_sysutil_sockaddr* p_sockaddr = 0;  vsf_sysutil_sockaddr_alloc(p_sockptr);  p_sockaddr = *p_sockptr;  if (p_src->u.u_sockaddr.sa_family == AF_INET)  {    p_sockaddr->u.u_sockaddr.sa_family = AF_INET;    vsf_sysutil_memcpy(&p_sockaddr->u.u_sockaddr_in.sin_addr,                       &p_src->u.u_sockaddr_in.sin_addr,                       sizeof(p_sockaddr->u.u_sockaddr_in.sin_addr));  }  else if (p_src->u.u_sockaddr.sa_family == AF_INET6)  {    p_sockaddr->u.u_sockaddr.sa_family = AF_INET6;    vsf_sysutil_memcpy(&p_sockaddr->u.u_sockaddr_in6.sin6_addr,                       &p_src->u.u_sockaddr_in6.sin6_addr,                       sizeof(p_sockaddr->u.u_sockaddr_in6.sin6_addr));  }  else  {    die("can only support ipv4 and ipv6 currently");  }}intvsf_sysutil_sockaddr_addr_equal(const struct vsf_sysutil_sockaddr* p1,                                const struct vsf_sysutil_sockaddr* p2){  int family1 = p1->u.u_sockaddr.sa_family;  int family2 = p2->u.u_sockaddr.sa_family;  if (family1 != family2)  {    if (family1 == AF_INET && family2 == AF_INET6)    {      const void* p_ipv4_addr = vsf_sysutil_sockaddr_ipv6_v4(p2);      if (p_ipv4_addr &&          !vsf_sysutil_memcmp(p_ipv4_addr, &p1->u.u_sockaddr_in.sin_addr,                              sizeof(p1->u.u_sockaddr_in.sin_addr)))      {        return 1;      }    }    else if (family1 == AF_INET6 && family2 == AF_INET)    {      const void* p_ipv4_addr = vsf_sysutil_sockaddr_ipv6_v4(p1);      if (p_ipv4_addr &&          !vsf_sysutil_memcmp(p_ipv4_addr, &p2->u.u_sockaddr_in.sin_addr,                              sizeof(p2->u.u_sockaddr_in.sin_addr)))      {        return 1;      }    }    return 0;  }  if (family1 == AF_INET)  {    if (vsf_sysutil_memcmp(&p1->u.u_sockaddr_in.sin_addr,                           &p2->u.u_sockaddr_in.sin_addr,                           sizeof(p1->u.u_sockaddr_in.sin_addr)) == 0)    {      return 1;    }  }  else if (family1 == AF_INET6)  {    if (vsf_sysutil_memcmp(&p1->u.u_sockaddr_in6.sin6_addr,                           &p2->u.u_sockaddr_in6.sin6_addr,                           sizeof(p1->u.u_sockaddr_in6.sin6_addr)) == 0)    {      return 1;    }  }  return 0;}intvsf_sysutil_sockaddr_is_ipv6(const struct vsf_sysutil_sockaddr* p_sockaddr){  if (p_sockaddr->u.u_sockaddr.sa_family == AF_INET6)  {    return 1;  }  return 0;}voidvsf_sysutil_sockaddr_set_ipv4addr(struct vsf_sysutil_sockaddr* p_sockptr,                                  const unsigned char* p_raw){  if (p_sockptr->u.u_sockaddr.sa_family == AF_INET)  {    vsf_sysutil_memcpy(&p_sockptr->u.u_sockaddr_in.sin_addr, p_raw,                       sizeof(p_sockptr->u.u_sockaddr_in.sin_addr));  }  else if (p_sockptr->u.u_sockaddr.sa_family == AF_INET6)  {    static struct vsf_sysutil_sockaddr* s_p_sockaddr;    vsf_sysutil_sockaddr_alloc_ipv4(&s_p_sockaddr);    vsf_sysutil_memcpy(&s_p_sockaddr->u.u_sockaddr_in.sin_addr, p_raw,                       sizeof(&s_p_sockaddr->u.u_sockaddr_in.sin_addr));    vsf_sysutil_memcpy(&p_sockptr->u.u_sockaddr_in6.sin6_addr,                       vsf_sysutil_sockaddr_ipv4_v6(s_p_sockaddr),                       sizeof(p_sockptr->u.u_sockaddr_in6.sin6_addr));  }  else  {    bug("bad family");  }}voidvsf_sysutil_sockaddr_set_ipv6addr(struct vsf_sysutil_sockaddr* p_sockptr,                                  const unsigned char* p_raw){  if (p_sockptr->u.u_sockaddr.sa_family == AF_INET6)  {    vsf_sysutil_memcpy(&p_sockptr->u.u_sockaddr_in6.sin6_addr, p_raw,                       sizeof(p_sockptr->u.u_sockaddr_in6.sin6_addr));  }  else  {    bug("bad family");  }

⌨️ 快捷键说明

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