📄 sysutil.c
字号:
}const void*vsf_sysutil_sockaddr_ipv6_v4(const struct vsf_sysutil_sockaddr* p_addr){ static char pattern[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF }; const unsigned char* p_addr_start; if (p_addr->u.u_sockaddr.sa_family != AF_INET6) { return 0; } if (vsf_sysutil_memcmp(pattern, &p_addr->u.u_sockaddr_in6.sin6_addr, 12)) { return 0; } p_addr_start = (const unsigned char*)&p_addr->u.u_sockaddr_in6.sin6_addr; return &p_addr_start[12];}const void*vsf_sysutil_sockaddr_ipv4_v6(const struct vsf_sysutil_sockaddr* p_addr){ static char ret[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF }; if (p_addr->u.u_sockaddr.sa_family != AF_INET) { return 0; } vsf_sysutil_memcpy(&ret[12], &p_addr->u.u_sockaddr_in.sin_addr, 4); return ret;}void*vsf_sysutil_sockaddr_get_raw_addr(struct vsf_sysutil_sockaddr* p_sockptr){ if (p_sockptr->u.u_sockaddr.sa_family == AF_INET) { return &p_sockptr->u.u_sockaddr_in.sin_addr; } else if (p_sockptr->u.u_sockaddr.sa_family == AF_INET6) { return &p_sockptr->u.u_sockaddr_in6.sin6_addr; } else { bug("bad family"); } return 0;}unsigned intvsf_sysutil_get_ipaddr_size(void){ struct vsf_sysutil_sockaddr addr; unsigned int size = sizeof(addr.u.u_sockaddr_in.sin_addr); unsigned int size2 = sizeof(addr.u.u_sockaddr_in6.sin6_addr); if (size2 > size) { size = size2; } return size;}intvsf_sysutil_get_ipsock(const struct vsf_sysutil_sockaddr* p_addr){ if (p_addr->u.u_sockaddr.sa_family == AF_INET) { return vsf_sysutil_get_ipv4_sock(); } else if (p_addr->u.u_sockaddr.sa_family == AF_INET6) { return vsf_sysutil_get_ipv6_sock(); } else { bug("bad family"); } return -1;}voidvsf_sysutil_sockaddr_set_any(struct vsf_sysutil_sockaddr* p_sockaddr){ if (p_sockaddr->u.u_sockaddr.sa_family == AF_INET) { vsf_sysutil_memclr(&p_sockaddr->u.u_sockaddr_in.sin_addr, sizeof(p_sockaddr->u.u_sockaddr_in.sin_addr)); } else if (p_sockaddr->u.u_sockaddr.sa_family == AF_INET6) { vsf_sysutil_memclr(&p_sockaddr->u.u_sockaddr_in6.sin6_addr, sizeof(p_sockaddr->u.u_sockaddr_in6.sin6_addr)); } else { bug("bad family"); }}voidvsf_sysutil_sockaddr_set_port(struct vsf_sysutil_sockaddr* p_sockptr, unsigned short the_port){ if (p_sockptr->u.u_sockaddr.sa_family == AF_INET) { p_sockptr->u.u_sockaddr_in.sin_port = htons(the_port); } else if (p_sockptr->u.u_sockaddr.sa_family == AF_INET6) { p_sockptr->u.u_sockaddr_in6.sin6_port = htons(the_port); } else { bug("bad family"); }}intvsf_sysutil_is_port_reserved(unsigned short the_port){ if (the_port < IPPORT_RESERVED) { return 1; } return 0;}const char*vsf_sysutil_inet_ntop(const struct vsf_sysutil_sockaddr* p_sockptr){ const struct sockaddr* p_sockaddr = &p_sockptr->u.u_sockaddr; if (p_sockaddr->sa_family == AF_INET) { return inet_ntoa(p_sockptr->u.u_sockaddr_in.sin_addr); } else if (p_sockaddr->sa_family == AF_INET6) { static char inaddr_buf[64]; const char* p_ret = inet_ntop(AF_INET6, &p_sockptr->u.u_sockaddr_in6.sin6_addr, inaddr_buf, sizeof(inaddr_buf)); inaddr_buf[sizeof(inaddr_buf) - 1] = '\0'; if (p_ret == NULL) { inaddr_buf[0] = '\0'; } return inaddr_buf; } else { die("can only support ipv4 and ipv6 currently"); return 0; }}const char*vsf_sysutil_inet_ntoa(const void* p_raw_addr){ return inet_ntoa(*((struct in_addr*)p_raw_addr));}intvsf_sysutil_inet_aton(const char* p_text, struct vsf_sysutil_sockaddr* p_addr){ struct in_addr sin_addr; if (p_addr->u.u_sockaddr.sa_family != AF_INET) { bug("bad family"); } if (inet_aton(p_text, &sin_addr)) { vsf_sysutil_memcpy(&p_addr->u.u_sockaddr_in.sin_addr, &sin_addr, sizeof(p_addr->u.u_sockaddr_in.sin_addr)); return 1; } else { return 0; }}voidvsf_sysutil_dns_resolve(struct vsf_sysutil_sockaddr** p_sockptr, const char* p_name){ struct hostent* hent = gethostbyname(p_name); if (hent == NULL) { die2("cannot resolve host:", p_name); } vsf_sysutil_sockaddr_clear(p_sockptr); if (hent->h_addrtype == AF_INET) { unsigned int len = hent->h_length; if (len > sizeof((*p_sockptr)->u.u_sockaddr_in.sin_addr)) { len = sizeof((*p_sockptr)->u.u_sockaddr_in.sin_addr); } vsf_sysutil_sockaddr_alloc_ipv4(p_sockptr); vsf_sysutil_memcpy(&(*p_sockptr)->u.u_sockaddr_in.sin_addr, hent->h_addr_list[0], len); } else if (hent->h_addrtype == AF_INET6) { unsigned int len = hent->h_length; if (len > sizeof((*p_sockptr)->u.u_sockaddr_in6.sin6_addr)) { len = sizeof((*p_sockptr)->u.u_sockaddr_in6.sin6_addr); } vsf_sysutil_sockaddr_alloc_ipv6(p_sockptr); vsf_sysutil_memcpy(&(*p_sockptr)->u.u_sockaddr_in6.sin6_addr, hent->h_addr_list[0], len); } else { die("gethostbyname(): neither IPv4 nor IPv6"); }}struct vsf_sysutil_user*vsf_sysutil_getpwuid(const int uid){ if (uid < 0) { bug("negative uid in vsf_sysutil_getpwuid"); } return (struct vsf_sysutil_user*) getpwuid((unsigned int) uid);}struct vsf_sysutil_user*vsf_sysutil_getpwnam(const char* p_user){ return (struct vsf_sysutil_user*) getpwnam(p_user);}const char*vsf_sysutil_user_getname(const struct vsf_sysutil_user* p_user){ const struct passwd* p_passwd = (const struct passwd*) p_user; return p_passwd->pw_name;}const char*vsf_sysutil_user_get_homedir(const struct vsf_sysutil_user* p_user){ const struct passwd* p_passwd = (const struct passwd*) p_user; return p_passwd->pw_dir;}intvsf_sysutil_user_getuid(const struct vsf_sysutil_user* p_user){ const struct passwd* p_passwd = (const struct passwd*) p_user; return p_passwd->pw_uid;}intvsf_sysutil_user_getgid(const struct vsf_sysutil_user* p_user){ const struct passwd* p_passwd = (const struct passwd*) p_user; return p_passwd->pw_gid;}struct vsf_sysutil_group*vsf_sysutil_getgrgid(const int gid){ if (gid < 0) { die("negative gid in vsf_sysutil_getgrgid"); } return (struct vsf_sysutil_group*) getgrgid((unsigned int) gid);}const char*vsf_sysutil_group_getname(const struct vsf_sysutil_group* p_group){ const struct group* p_grp = (const struct group*) p_group; return p_grp->gr_name;}unsigned charvsf_sysutil_get_random_byte(void){ static int seeded; unsigned int uint_res; unsigned char c1, c2, c3, c4; if (!seeded) { struct timeval tv; int retval = gettimeofday(&tv, NULL); if (retval != 0) { die("gettimeofday"); } srand((unsigned)tv.tv_usec); seeded = 1; } uint_res = rand(); c1 = uint_res & 0x000000ff; c2 = (uint_res >> 8) & 0x000000ff; c3 = (uint_res >> 16) & 0x000000ff; c4 = (uint_res >> 24) & 0x000000ff; return c1 ^ c2 ^ c3 ^ c4; }intvsf_sysutil_running_as_root(void){ return (getuid() == 0);}voidvsf_sysutil_setuid(const struct vsf_sysutil_user* p_user){ const struct passwd* p_passwd = (const struct passwd*) p_user; vsf_sysutil_setuid_numeric(p_passwd->pw_uid);}voidvsf_sysutil_setuid_numeric(int uid){ int retval = setuid(uid); if (retval != 0) { die("setuid"); }}voidvsf_sysutil_setgid(const struct vsf_sysutil_user* p_user){ const struct passwd* p_passwd = (const struct passwd*) p_user; vsf_sysutil_setgid_numeric(p_passwd->pw_gid);}voidvsf_sysutil_setgid_numeric(int gid){ int retval = setgid(gid); if (retval != 0) { die("setgid"); }}intvsf_sysutil_geteuid(void){ int retval = geteuid(); if (retval < 0) { die("geteuid"); } return retval;}intvsf_sysutil_getegid(void){ int retval = getegid(); if (retval < 0) { die("getegid"); } return retval;}voidvsf_sysutil_seteuid(const struct vsf_sysutil_user* p_user){ const struct passwd* p_passwd = (const struct passwd*) p_user; vsf_sysutil_seteuid_numeric(p_passwd->pw_uid);}voidvsf_sysutil_setegid(const struct vsf_sysutil_user* p_user){ const struct passwd* p_passwd = (const struct passwd*) p_user; vsf_sysutil_setegid_numeric(p_passwd->pw_gid);}voidvsf_sysutil_seteuid_numeric(int uid){ /* setreuid() would seem to be more portable than seteuid() */ int retval = setreuid(-1, uid); if (retval != 0) { die("seteuid"); }}voidvsf_sysutil_setegid_numeric(int gid){ /* setregid() would seem to be more portable than setegid() */ int retval = setregid(-1, gid); if (retval != 0) { die("setegid"); }}voidvsf_sysutil_clear_supp_groups(void){ int retval = setgroups(0, NULL); if (retval != 0) { die("setgroups"); }}voidvsf_sysutil_initgroups(const struct vsf_sysutil_user* p_user){ const struct passwd* p_passwd = (const struct passwd*) p_user; int retval = initgroups(p_passwd->pw_name, p_passwd->pw_gid); if (retval != 0) { die("initgroups"); }}voidvsf_sysutil_chroot(const char* p_root_path){ int retval = chroot(p_root_path); if (retval != 0) { die("chroot"); }}unsigned intvsf_sysutil_get_umask(void){ return s_current_umask;}voidvsf_sysutil_set_umask(unsigned int new_umask){ s_current_umask = (new_umask & 0777); (void) umask(s_current_umask);}voidvsf_sysutil_make_session_leader(void){ /* This makes us the leader if we are not already */ (void) setsid(); /* Check we're the leader */ if (getpid() != getpgrp()) { die("not session leader"); }}voidvsf_sysutil_tzset(void){ int retval; char tzbuf[sizeof("+HHMM!")]; time_t the_time = time(NULL); struct tm* p_tm; tzset(); p_tm = localtime(&the_time); if (p_tm == NULL) { die("localtime"); } /* Set our timezone in the TZ environment variable to cater for the fact * that modern glibc does not cache /etc/localtime (which becomes inaccessible * when we chroot(). */ retval = strftime(tzbuf, sizeof(tzbuf), "%z", p_tm); tzbuf[sizeof(tzbuf) - 1] = '\0'; if (retval == 5) { /* Static because putenv() does not copy the string. */ static char envtz[sizeof("TZ=UTC-hh:mm")]; /* Insert a colon so we have e.g. -05:00 instead of -0500 */ tzbuf[5] = tzbuf[4]; tzbuf[4] = tzbuf[3]; tzbuf[3] = ':'; /* Invert the sign - we just got the offset _from_ UTC but for TZ, we need * the offset _to_ UTC. */ if (tzbuf[0] == '+') { tzbuf[0] = '-'; } else { tzbuf[0] = '+'; } snprintf(envtz, sizeof(envtz), "TZ=UTC%s", tzbuf); putenv(envtz); s_timezone = ((tzbuf[1] - '0') * 10 + (tzbuf[2] - '0')) * 60 * 60; s_timezone += ((tzbuf[4] - '0') * 10 + (tzbuf[5] - '0')) * 60; if (tzbuf[0] == '-') { s_timezone *= -1; } }}const char*vsf_sysutil_get_current_date(void){ static char datebuf[64]; time_t curr_time; const struct tm* p_tm; int i = 0; vsf_sysutil_update_cached_time(); curr_time = vsf_sysutil_get_cached_time_sec(); p_tm = localtime(&curr_time); if (strftime(datebuf, sizeof(datebuf), "%a %b!%d %H:%M:%S %Y", p_tm) == 0) { die("strftime"); } datebuf[sizeof(datebuf) - 1] = '\0'; /* This hack is because %e in strftime() isn't so portable */ while (datebuf[i] != '!' && datebuf[i] != '\0') { ++i; } if (datebuf[i] == '!') { datebuf[i] = ' '; if (datebuf[i+1] == '0') { datebuf[i+1] = ' '; } } return datebuf;}voidvsf_sysutil_update_cached_time(void){ if (gettimeofday(&s_current_time, NULL) != 0) { die("gettimeofday"); }}longvsf_sysutil_get_cached_time_sec(void){ return s_current_time.tv_sec;}longvsf_sysutil_get_cached_time_usec(void){ return s_current_time.tv_usec;}voidvsf_sysutil_qsort(void* p_base, unsigned int num_elem, unsigned int elem_size, int (*p_compar)(const void *, const void *)){ qsort(p_base, num_elem, elem_size, p_compar);}voidvsf_sysutil_sleep(double seconds){ int retval; int saved_errno; double fractional; time_t secs; struct timespec ts; secs = (time_t) seconds; fractional = seconds - (double) secs; ts.tv_sec = secs; ts.tv_nsec = (long) (fractional * (double) 1000000000); do { retval = nanosleep(&ts, &ts); saved_errno = errno; vsf_sysutil_check_pending_actions(kVSFSysUtilUnknown, 0, 0); } while (retval == -1 && saved_errno == EINTR);}char*vsf_sysutil_getenv(const char* p_var){ return getenv(p_var);}voidvsf_sysutil_openlog(void){ int facility = LOG_DAEMON;#ifdef LOG_FTP facility = LOG_FTP;#endif openlog("vsftpd", LOG_NDELAY, facility);}voidvsf_sysutil_syslog(const char* p_text, int severe){ int prio = LOG_INFO; if (severe) { prio = LOG_WARNING; } syslog(prio, "%s", p_text);}longvsf_sysutil_parse_time(const char* p_text){ struct tm the_time; unsigned int len = vsf_sysutil_strlen(p_text); vsf_sysutil_memclr(&the_time, sizeof(the_time)); if (len >= 8) { char yr[5]; char mon[3]; char day[3]; vsf_sysutil_strcpy(yr, p_text, 5); vsf_sysutil_strcpy(mon, p_text + 4, 3); vsf_sysutil_strcpy(day, p_text + 6, 3); the_time.tm_year = vsf_sysutil_atoi(yr) - 1900; the_time.tm_mon = vsf_sysutil_atoi(mon) - 1; the_time.tm_mday = vsf_sysutil_atoi(day); } if (len >= 14) { char hr[3]; char mins[3]; char sec[3]; vsf_sysutil_strcpy(hr, p_text + 8, 3); vsf_sysutil_strcpy(mins, p_text + 10, 3); vsf_sysutil_strcpy(sec, p_text + 12, 3); the_time.tm_hour = vsf_sysutil_atoi(hr); the_time.tm_min = vsf_sysutil_atoi(mins); the_time.tm_sec = vsf_sysutil_atoi(sec); } return mktime(&the_time);}intvsf_sysutil_setmodtime(const char* p_file, long the_time, int is_localtime){ struct utimbuf new_times; if (!is_localtime) { the_time -= s_timezone; } vsf_sysutil_memclr(&new_times, sizeof(new_times)); new_times.actime = the_time; new_times.modtime = the_time; return utime(p_file, &new_times);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -