《UNIX环境高级编程》笔记 第六章 系统数据文件和信息

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);
int initgroups(const char *user, gid_t group);

获取/设置附属组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. 掌握各个时间和日期函数的理解和使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值