UNIX系统的正常运作需要使用大量与系统有关的数据文件,例如,口令文件/etc/passwd和组文件/etc/group等。
1、口令文件
口令文件的各字段包含在pwd.h>中定义的passwd结构中:
struct passwd 成员 | 说明 |
---|---|
char *pw_name | 用户名 |
char *pw_passwd | 加密口令 |
uid_t pw_uid | 数值用户ID |
gid_t pw_gid | 数值组ID |
char *pw_gecos | 注释字段 |
char *pw_dir | 初始工作目录 |
char *pw_shell | 初始shell |
char *pw_class | 用户访问类 |
time_t pw_change | 下次更改口令时间 |
time_t pw_expire | 账户有效期时间 |
通过用户登录名或数值用户ID获取口令文件项:
#include <pwd.h>
struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *name);
若成功,返回指针;若出错,返回NULL
查看整个口令文件:
#include <pwd.h>
struct passwd *getpwent(void); //返回口令文件中的下一个记录项
若成功,返回指针;若出错或到达文件尾端,返回NULL
void setpwent(void);//反绕它所使用的文件
void endpwent(void);//关闭文件
2、阴影口令
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 | 保留 |
注:只有用户登录名和加密口令这两个字段是必须的。
#include <shadow.h>
struct spwd *getspnam(const char *name);
struct spwd *getspent(void);
若成功,返回指针,若出错,返回NULL
void setspent(void);
void endspent(void);
3、组文件
struct group 成员 | 说明 |
---|---|
char *gr_name | 组名 |
char *gr_passwd | 加密口令 |
int gr_gid | 数值组ID |
char **gr_mem | 指向各用户名指针的数组 |
#include <grp.h>
struct group *getgrgid(gid_t gid);
struct group *getgrnam(const char *name);
若成功,返回指针;若出错,返回NULL
#include <grp.h>
struct group *getgrent(void);
若成功,返回指针;若出错,返回NULL
void setgrent(void)
void endgrent(void);
4、附属组ID
文件访问权限检查:不仅将进程的有效组ID与文件的组ID相比较,而且也将所有附属组ID与文件的组ID进行比较。
#include <unistd.h>
int getgroups(int gidsetsize,gid_t grouplist[]);
若成功,返回附属组ID数量;若出错,返回-1
#include <grp.h>
int setgroups(int ngroups,const gid_t grouplist[]);
int initgroups(const char *username,gid_t basegid);
若成功,返回0;若出错,返回-1
getgroups将进程所属用户的各附属组ID填写到数组grouplist中,填写入该数组的附属组ID数最多为gidsetsize个。
setgroups可由超级用户调用以便为调用进程设置附属组ID表。
5、其他数据文件
一般情况下,对于每个数据文件至少有3个函数:
(1)get函数,读下一个记录,通常返回指向一个结构的指针。
(2)set函数,打开相应数据文件,然后反绕该文件。
(3)end函数,关闭相应数据文件。
6、登陆账户记录
utmp文件记录当前登陆到系统的各个用户;
wtmp文件跟踪各个登陆和注销事件。
struct tmp{
char ut_line[8];
char t_name[8];
long ut_time;
};
登录时,login程序填写此类型结构,然后将其写入到utmp文件中,同时也将其添写到wtmp文件中。注销时,init进程将utmp文件中相应的记录擦除,并将一个新纪录添写到wtmp文件中。
7、时间和日期例程
#include <time.h>
time_t time(time_t *calptr);//时间值作为函数值返回,也存放在由calptr指向的单元中
若成功,返回时间值,若出错,返回-1
time_t:日历时间,自协调世界时公元1970年1月1日00:00:00以来经过的秒数。
#include <sys/time.h>
int clock_gettime(clockid_t clock_id.struct timespec *tsp);
int clock_getres(clockid_t clock_id.struct timespec *tsp);
int clock_settime(clockid_t clock_id.struct timespec *tsp);
若成功,返回0;若出错,返回-1
#include <sys/time.h>
int gettimeofdat(struct timeval *restrict tp,void *restrict tzp);
总是返回0
tzp的唯一合法值是NULL。
函数localtime和gmtime将日历时间转换成分解的时间,并存放在一个tm结构中:
struct tm{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
#include <time.h>
struct tm *gmtime(const time_t *calptr);
struct tm *localtime(const time_t *calptr);
函数mktime以本地时间的年月日等作为参数,将其变换成time_t值:
#include <time.h>
time_t mktime(struct tm *tmptr);
#include <time.h>
size_t strftime(char *restrict buf,size_t maxsize,
const char *restrictt format,
const struct tm *restrict tmptr);
size_t strftime_1(char *restrict buf,size_t maxsize,
const char *restrictt format,
const struct tm *restrict tmptr,
若有空间,返回存入数组的字符数,否则,返回0
#include <time.h>
char *strptime(const char *restrict buf,
const char *restrict format,
struct tm *restrict tmptr);