1. 简介
本章介绍了口令文件(/etc/passwd)、阴影口令(/etc/shadow)、组文件(/etc/group)及其他几个系统数据文件的相关信息、作用和读写接口,后面还涉及了时间和日期相关的API。
2. 函数原型
struct passwd *getpwent(void); void setpwent(void); void endpwent(void); | 操作口令文件 getpwent 读取文件的一个条目,返回值:若成功,返回指针;若出错或到达文件末尾,返回NULL setpwent 反绕文件,重新定位到文件开始处 endpwent 关闭文件 |
struct spwd *getspnam(const char *name); struct spwd *getspent(void); void setspent(void); void endspent(void); | 操作阴影口令文件 |
struct group *getgrnam(const char *name); struct group *getgrgid(gid_t gid); struct group *getgrent(void); void setgrent(void); void endgrent(void); | 操作组文件 |
int getgroups(int size, gid_t list[]); int setgroups(size_t size, const gid_t *list); | 获取/设置附属组ID |
int getnameinfo(const struct sockaddr *addr, socklen_t addrlen,char *host, socklen_t hostlen,char *serv, socklen_t servlen, int flags); int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); | 操作/etc/hosts |
struct netent *getnetent(void); struct netent *getnetbyname(const char *name); struct netent *getnetbyaddr(uint32_t net, int type); void setnetent(int stayopen); void endnetent(void); | 操作/etc/networks |
struct protoent *getprotoent(void); struct protoent *getprotobyname(const char *name); struct protoent *getprotobynumber(int proto); void setprotoent(int stayopen); void endprotoent(void); | 操作/etc/protocols |
struct servent *getservent(void); struct servent *getservbyname(const char *name, const char *proto); struct servent *getservbyport(int port, const char *proto); void setservent(int stayopen); void endservent(void); | 操作/etc/services |
int uname(struct utsname *name) | 返回主机和操作系统有关信息 |
int gethostname(char *name, size_t len); int sethostname(const char *name, size_t len); | 返回/设置主机名字 |
time_t time(time_t *tloc); | 返回自1970-01-01 00:00:00以来经过的秒数 |
int clock_getres(clockid_t clk_id, struct timespec *res); int clock_gettime(clockid_t clk_id, struct timespec *tp); int clock_settime(clockid_t clk_id, const struct timespec *tp); | 根据时钟ID来获取/设置时间 |
int gettimeofday(struct timeval *tv, struct timezone *tz); int settimeofday(const struct timeval *tv, const struct timezone *tz); | 获取/设置日历时间,比time函数精度更高 |
struct tm *gmtime(const time_t *timep); struct tm *localtime(const time_t *timep); | 将时间转换为世界协调时或本地时间,年、月、日、时、分、秒、周日的分解结构 |
time_t mktime(struct tm *tm); | 将年、月、日、时、分、秒、周日的分解结构转换为所经历的秒数(1970-01-01 00:00:00) |
size_t strftime(char *s, size_t max, const char *format, const struct tm *tm); | 字符串输出格式化日期和时间 |
3. 实例
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
#include <shadow.h>
#include <grp.h>
#include <time.h>
#include <unistd.h>
void scan_passwd()
{
struct passwd *pwd = NULL;
printf("scan_passwd*************\n");
setpwent();
do {
pwd = getpwent();
if (pwd) {
printf("username: %-20s user id: %04d group id: %04d\n", pwd->pw_name, pwd->pw_uid, pwd->pw_gid);
}
} while(pwd != NULL);
endpwent();
}
// Root user privileges are required
void scan_shadow()
{
struct spwd *pwd = NULL;
printf("scan_shadow*************\n");
setspent();
do {
pwd = getspent();
if (pwd) {
printf("username: %-20s passwd: %s\n", pwd->sp_namp, pwd->sp_pwdp);
}
} while(pwd != NULL);
endspent();
}
void scan_group()
{
struct group *grp= NULL;
printf("scan_group*************\n");
setgrent();
do {
grp = getgrent();
if (grp) {
printf("username: %-20s group id: %d\n", grp->gr_name, grp->gr_gid);
}
} while(grp != NULL);
endgrent();
}
int main()
{
scan_passwd();
scan_shadow();
scan_group();
time_t tim = time(NULL);
printf("time = %ld\n", tim);
struct tm *tm = gmtime(&tim);
if (tm) {
if (tm->tm_hour > 12) {
tm->tm_hour -= 12;
}
//Run shell command: date -u
printf("time = %d-%d-%d %d:%d:%d\n",
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
char buf[64] = {0};
strftime(buf, sizeof(buf)-1, "%D %T", tm );
printf("buf time = %s\n", buf);
}
clockid_t clk_ids[] = {CLOCK_REALTIME, CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID, CLOCK_MONOTONIC};
for (int i = 0; i < sizeof(clk_ids)/sizeof(clk_ids[0]); i++) {
struct timespec tp = {0};
clock_gettime(clk_ids[i], &tp);
printf("%012ld %ld\n", tp.tv_sec, tp.tv_nsec);
}
#if 1
sleep(3);
#else
int n = 1000000000;
while (--n);
#endif
printf("After\n");
for (int i = 0; i < sizeof(clk_ids)/sizeof(clk_ids[0]); i++) {
struct timespec tp = {0};
clock_gettime(clk_ids[i], &tp);
printf("%012ld %ld\n", tp.tv_sec, tp.tv_nsec);
}
}
4. 小结
1. 了解各个系统数据文件的相关作用及内容
2. 掌握各个时间和日期函数的理解和使用