unix系统的口令文件包含下面的各字段,这些字段包含在<pwd.h>中定义的passwd结构中。
Description | struct passwd member | POSIX.1 | FreeBSD 5.2.1 | Linux 2.4.22 | Mac OS X 10.3 | Solaris 9 |
---|---|---|---|---|---|---|
user name | char *pw_name | • | • | • | • | • |
encrypted password | char *pw_passwd | • | • | • | • | |
numerical user ID | uid_t pw_uid | • | • | • | • | • |
numerical group ID | gid_t pw_gid | • | • | • | • | • |
comment field | char *pw_gecos | • | • | • | • | |
initial working directory | char *pw_dir | • | • | • | • | • |
initial shell (user program) | char *pw_shell | • | • | • | • | • |
user access class | char *pw_class | • | • | |||
next time to change password | time_t pw_change | • | • | |||
account expiration time | time_t pw_expire | • | • |
POSIX.1定义了两个获取口令文件项的函数。
struct passwd *getpwuid(uid_t uid)
struct passwd *getpwanm(const char *name);
这两个函数都返回一个指向passwd结构的指针。该结构已由这两个函数在执行时填入信息。上述两个函数只能实现查看登录名和ID。
如果要查看整个口令文件,则下面三个函数可以:
void setpwent(void)
void endpwent(void)
struct passwd *getpwent(void)
对于第三个函数,如果成功,返回指针。如果出错或者达到文件尾则返回NULL。
案列:getpwnam.c的实现。
getpwnam.c:
#include <pwd.h>
#include <stddef.h>
#include <string.h>
struct passwd *getpwnam(const char *name)
{
struct passwd *ptr;
setpwent();
while ((ptr = getpwent()) != NULL)
if (strcmp(name, ptr->pw_name) == 0)
break;
endpwent();
return(ptr);
}
6.3阴影口令
用户的密码保存在文件/etc/passwd文件中。我们可以用下面几个函数访问这个文件:struct spwd *getspnam(const char *name)
struct spwd *getspent(void)
这两个函数若成功返回指针,若失败返回NULL。
void setspent(void)
void endspent()
这两个函数原理与前面的一样。
6.4组文件
UNIX的组文件的数据结构包含在<grp.h>中。struct group
{
char *gr_name;
char *gr_passwd
int gr_gid;
char **gr_name
}
我们可以用下面函数来查看组名和组ID.
struct group *getgrgid(gid_t gid)
struct group *getgrnam(const char *name)
如果要搜索整个组文件,则需要下面几个函数:
struct group *getgrent(void)
void setgrent(void)
void endgrent(void)
setgrent打开组文件并反饶他,getgrent从组文件中读取一个记录。最后用endgrent关闭它。
6.8登陆账户记录
unix系统提供两个文件,utmp文件,它记录当前登陆进系统的各个用户。wtmp文件,它跟踪各个登陆和注销事件。
struct utmp
{
char ut_line[8];
char ut_name[8];
long ut_time:
}
登陆时,login程序填写次类型结构,然后写入utmp文件中。同时也添加到wtmp文件中。
6.9系统标识
我们可以用uname函数返回与当前主机和操作系统有关的信息。int uname(struct utsname *name)
若成功则返回非负值,若出错则返回-1。
我们提供utsname结构,然后函数填写该结构:
struct utsname
{
char sysname[];
char nodename();
char release[];
char version[];
char machine[];
}
我们可以通过gethostname来得到主机名。
int gethostname(char *name, int namelen)
6.10时间和日期例程
UNIX系统用1970年1月1日经过的秒数来计算事件,数据类型是time_t表示。我们可以通过time函数返回当前时间和日期。
time_t time(time_t *calptr)
通过gettimeofday提供更高级别的分辨率。
int gettimeofday(struct timeval *restrict tp,void *restrict tzp)
第二个参数唯一的合法值是NULL。
第一个参数是存取时间的timeval结构中。存储秒和微秒。
struct timeval
{
time_t tv_sec;
long tv_usec;
}
我们可以通过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;
}
可以用下面的函数得到上面的结构:
struct tm *gmtime(const time_t *calptr)
struct tm *localtime(const time_t *calptr)
函数mktime以本地事件的年、月、日参数。返回转换成time_t值。
time_t mktime(struct tm * tmptr);
下面两个函数可以把时间转换成date命令显示模式的样式。
char *asctime(const struct tm *tmptr)
char *ctime(const time_t *calptr)