APUE第6章 系统数据文件和信息

1、概述

UNIX系统的正常运作需要使用大量与系统有关的数据文件,例如,口令文件/etc/passwd和组文件/etc/group就是经常被多个程序频繁使用的两个文个件。用户每次登录UNIX系统,以及每次执行ls -l命令时都要使用口令文件。

2、口令文件/etc/passwd

UNIX系统的口令文件包含如下字段,且这些字段包含在中定义的passwd结构中。

用户名(char *pw_name)、加密口令(char* pw_passwd)、数值用户ID(uid_t pw_uid)、数值组ID(gid_t pw_gid)、注释字段(char* pw_gecos)、初始工作目录(char* pw_dir)、初始shell(用户程序)(char* pw_shell)、用户访问类(char* pw_class)、下次更改口令时间(time_t pw_change)、账户有效期时间(time_t pw_expire)。

举例:tyliang:x:1000:1000:tyliang,,,:/home/tyliang:/bin/bash

值得注意地方:

i、通常有一个用户名为root的登录项,其用户ID为0

ii、加密口令字段包含了一个占位符。我们无法看见密码的,嘿嘿!

iii、shell字段包含了一个可执行程序名,它被用作该用户的登录shell。

iv、为了阻止一个特定用户登录系统。除使用/dev/null外,其他替代方法:将/bin/false用作登录shell(以不成功状态终止);用/bin/true禁止一个账户(以成功状态终止);用nologin命令,打印可定制的出错信息,然后以非0状态终止。

v、finger命令支持注释字段中的附加信息。如:finger -p tyliang   从而可以查看tyliang用信息。

3、阴影口令/etc/shadow

某些系统将加密口令存放在一个通常称为阴影口令的文件中。该文件至少包含用户名和加密口令。只有root权限才有资格查看。

/etc/shadow文件中的字段
说明 struct spwd成员
用户登录名 char* sp_namp
加密口令 char* sp_pwdp
上次更改口令以来经过的时间 int sp_lstchg
经多少天后允许更改 int sp_min
要求更改尚余天数 int sp_max
超期警告天数 int sp_warn
账户不活动之前尚余天数 int sp_inact
账户超期天数 int sp_expire
保留 unsigned int sp_flag

4、组文件

UNIX组文件包含如下表的所示字段。这此字段包含在中所定义的group结构中。

/etc/group文件中字段
说明 struct group成员
组名 char* gr_name
加密口令 char* gr_passwd
数值组ID int gr_gid
指向各用户名指针的数组 char** gr_mem

字段gr_mem是一个指针数组,其中每个指针指向一个属于该组的用户名。该数组以null指针结尾。

5、其他数据文件

访问系统数据文件的一些例程
说明 数据文件 头文件 结构 附加的键搜索函数
口令 /etc/passwd passwd getpwnam、getpwuid
/etc/group group getgrnam、getgrgid
阴影 /etc/shadow spwd getspnam
主机 /etc/hosts hostent getnameinfo、getaddrinfo
网络 /etc/networks netent getnetbyname、getnetbyaddr
协议 /etc/protocols protoent getprotobyname、getprotobynumber
服务 /etc/services servent getservbyname、getservbyport

6、登录账户记录、系统标识

i、UNIX系统提供下列两个数据文件:utmp文件记录当前登录到系统的各个用户;wtmp文个把跟踪各个登录和注销事件。

一般而言,利用who命令读取utmp文件,last命令读取wtmp文件。

ii、uname函数返回与主机和操作系统有关的信息

#include
int uname(struct utsname* name);
		//返回值:若成功,返回非负值,若出错,返回-1
struct utsname {
	char sysname[];/* name of the operating system*/
	char nodename[];/* name of this node */
	char release[];/* current release of operating system*/
	char version[];/* current version of this release */
	char machine[];/* name of hardware type */
};

utsname结构中的信息通常可用uname命令打印。

 

gethostname函数:只返回主机名,该名字通常就是tcp/ip网络上主机的名字。

#include
int gethostname(char* name, int namelen);
		//返回值:若成功,返回非负值,若出错,返回-1

namelen参数指定name缓冲区长度,如若提供足够的空间,则通过name返回的字符串以null字节结尾。如若没有提供足够的空间,则没有说明通过name返回的字符串是否以null结尾。

hostname命令可用来获取和设置主机名。(超级用户用一个类似的函数sethostname来设置主机名。)主机名通常在系统自举时设置,它由/etc/rc或init取自一个启动文件。

7、时间和日期例程

日历时间:以1970年1月1日为准,经过的时间以秒来计算,其类型为time_t。

分解时间:即存储年月日时分秒,通过一定组合可以转换成我们熟悉的时间表示。

i、time函数返回当前时间和日期。

#include
time_t time(time_t *calptr);
		//返回值:若成功,返回时间值,若出错,返回-1

时间值作为函数值返回。如果参数非空,则时间值也存放在由calptr指向的单元内。

mktime函数将本地时间的年月日等作为参数,转变为time_t值。

#include
time_t mktime(struct tm* tmptr);
		//返回值:若成功,返回日历时间;若出错,返回-1

ii、两个函数localtime和gmtime将日历时间转换成分解的时间,并将这些存放在一个tm结构中。

#include
struct tm* gmtime(const time_t * calptr);
struct tm* localtime(const time_t * calptr);
		//两个函数的返回值:指向分解的tm结构的指针;若出错,返回NULL

localtime和gmtime之间的区别是:localtime将日历时间转换成本地时间(考虑到本地时区和夏令时标志),而gmtime则将日历时间转换成协调统一时间的年、月、日、时、分、秒、周日分解结构。

iii、strftime是一个类似于printf的时间值函数。可通过可用的多个参数来定制产生的字符串。

#include
size_t strftime(char* restrict buf, size_t maxsize, const char *restrict format,
	const struct tm* restrict tmptr);//将分解时间转换成字符串,其中tmptr参数由localtime函数获取
size_t strftime_l(char* restrict buf, size_t maxsize, const char *restrict format,
	const struct tm* restrict tmptr,locale_t locale);
		//两个函数的返回值:若有空间,返回存入数组的字符数;否则,返回0

strftime_l允许调用者将区域指定为参数。strftime使用通过TZ环境变量指定的区域。

tmptr参数是要格式化的时间值,由一个指向分解时间值tm结构的指针说明。

format参数控制时间值的格式。如同printf函数一样,转换说明的形式是百分号之后跟一个特定字符。

该部分具体参考书P154-P156。

下图是各个函数之间的转换关系。

APUE第6章 系统数据文件和信息_第1张图片

以下是获取本时间的程序:

#include"apue.h"
#include

int main(){
	time_t caltime;
	struct tm *tm;
	char line[MAXLINE];

	if((caltime=time(NULL))==-1)//调用time函数返回日历时间
		err_sys("time_error");
	if((tm=localtime(&caltime))==NULL)//将日历时间转换为本地的分解时间
		err_sys("localtime error");
	if(strftime(line,MAXLINE,"%a %b %X %Z %Y\n",tm)==0)//将分解时间格式化为字符串
		err_sys("strftime error");
	fputs(line,stdout);//将字符串输出到标准输出中
	exit(0);
}

 

你可能感兴趣的:(apue)