zoukankan      html  css  js  c++  java
  • Apue.2e chapter6

    本章学习系统数据文件的接口,以及系统标识函数、时间和日期等信息函数。

    口令文件:/etc/passwd

    #include <pwd.h>

    struct passwd{

        char *pw_name;    //用户名    *

        char *pw_passwd;    //加密口令

        uid_t pw_uid;        //user id    *

        gid_t pw_gid;        //group id    *

        char *pw_gecos;    //注释

        char *pw_dir;        //初始目录    *

        char *pw_shell;        //shell menu    *

        char *pw_class;        //用户访问类

        time_t pw_change;    //下次更改口令时间

        time_t pw_expire;    //账户到期时间

    };

    *指的是POSIX.1规定的必须项;

    使用finger命令可解析指定用户的相关信息。

    相关函数(POSIX):

    #include <pwd.h>

    struct passwd *getpwuid(uid_t uid);

    struct passwd *getpwnam(const char *name);

    通过name或uid获得passwd结构的内容。返回的指针其实指向一个静态变量,所以每次调用都会覆盖上次的结果,注意保存副本,下同。

    SUS扩展:

    struct passwd *getpwent(void);    //返回口令文件下一记录项

    void setpwent();        //打开口令文件;若已经打开,则偏移量调回开始处。rewind,书中翻译为反绕

    void endpwent();//关闭口令文件

    用户密码段在/etc/passwd中仅有一个占位符,真正的密码存放在/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;    //保留

    };

    sp是shadow password的缩写,其中只有*的两项是必须的,其余都是附加字段。相关函数

    #include <shadow.h>

    struct spwd *getspnam(const char *name);

    struct spwd *getspent();

    void setspent();

    void endspent();

    木有通过UID获取的函数;以上函数在Linux和Solaris上可用;但是freeBSD和MacOS上口令就不是用这种存放方式了。

    组文件:/etc/group

    #include <grp.h>

    struct group{

        char *gr_name;        //组名        *

        char *gr_passwd;    //加密口令    

        int gr_gid;        //组ID        *

        char **gr_mem;    //字符串数组,指向各用户名    *

    };

    除口令外皆POSIX.1定义的必须项。

    相关函数:

    struct group *getgrgid(gid_t gid);

    struct group *getgrnam(const char *name);

    //SUS:

    struct group *getgrent();

    void setgrent();

    void endgrent();

    附加组ID

    常量NGROUPS_MAX规定了附加组的数量限制。相关函数:

    #include <unistd.h>

    ing getgroups(int gidsetsize, gid_t grouplist[]);    //填充附加组ID,POSIX.1. 若gidsetsize=0,返回附加组ID数;

    //然后再调用一次,gidsetsize可作为限制。

    #include <grp.h>    //on linux, SUS,以下都是su权限操作

    #include <unistd.h>    //others

    int setgroups(int ngroups, const gid_t grouplist[]);    //给调用进程设置附加组ID表

    int initgroups(const char *username, gid_t basegid);    //初始化附加组ID表,一般很少调用。

    其他信息

    其他信息,包括服务(/etc/services),网络(/etc/networks)和协议(/etc/protocols)等等,相关函数有形式上的相似性,包括:

    get函数:读下一个记录,返回一个指向静态结构的指针(大多数情况)

    set函数:打开文件,或rewind已经打开的文件

    end函数:关闭文件

    还有若干关键字搜索的函数:getxxbyname和getxxbyaddr等等。具体的可以查阅相关头文件。如netdb.h

    登录账户记录

    utmp文件:记录当前登录进系统各个用户;shell: who

    wtmp:记录各个登录和注销事件;shell: last

    在Linux中,可以用man 5 utmp获得相关信息

    系统标识

    #include <sys/utsname.h>

    int uname(struct ustname *name);

    struct utsname{

        char sysname[];        //系统名称

        char nodename[];    //当前结点名称

        char release[];        //发行版编号

        char version[];        //当前发行版版本号

        char machine[];        //机器名称

    };

    如果在TCP/IP网络中,可以使用gethostname(char *name,int namelen)获取主机名称(完全限定名),shell: hostname。

    时间和日期相关

    time函数返回当前时间(日历时间)。但是SUS木有规定如何设置当前时间…╮(╯Д╰)╭

    #include <sys/time.h>

    struct timval{

        time_t tv_sec;        //seconds

        long tv_usec;        //microseconds

    };

    int gettimeofday(struct timeval *restrict tp, void *restrict tzp);    //SUS

    总是返回0;

    tzp只能是NULL(囧),否则不可移植。本函数提供比time函数更高精度的填充值。

    time_t可以经过多个函数转化为可读性更好的时间值,包括:

    #include <time.h>

    struct tm *gmtime(const time_t *calptr);    //转为国际标准时间UTC

    struct tm *localtime(const time_t *calptr);    //转为本地时间CST

    struct tm{

        int tm_sec;    //0~60,考虑到闰秒

        int tm_min;

        int tm_hour;

        int tm_mday;

        int tm_mon;

        int tm_year;    //years since 1900

        int tm_wday;    //周几,从周日开始

        int tm_yday;    //从1月1号开始过了几天

        int tm_isdst;    //夏时制

    };

    mktime进行struct tm*到time_t的反相转换;

    asctime和ctime分别将struct tm *和time_t *转为字符串形式,形式上同shell: date的输出;

    strftime具有非常复杂的格式化输出…类似printf:

    #include <time.h>

    size_t strftime(char *restrict buf, size_t maxsize,

            const char *restrict format,

            const struct tm *restrict tmptr);

    format指定格式,格式化结果存放在长度为maxsize的buf中。返回存放字符数(不含\0),如果buf长度不足,返回0;

    以上函数中,除了asctime和gmtime外都受到时区设置(环境变量TZ)的影响;

    这一部分除了SUS外,都是ISO C规定的函数(time.h)

    习题里面最后一题,貌似没有办法直接生成汉字的输出,给的答案也不行,估计要自行格式化了…

  • 相关阅读:
    页面返回顶部的方法总结
    举个栗子学习JavaScript设计模式
    深入理解css3中nth-child和 nth-of-type的区别
    HTML5笔记2——HTML5音/视频标签详解
    Chrome DevTools – 键盘和UI快捷键参考
    js中this关键字测试集锦
    JavaScript学习总结(三)——this、原型、javascript面向对象
    javascript移动设备Web开发中对touch事件的封装实例
    手机兼容集锦
    谈谈常用清除浮动的方法
  • 原文地址:https://www.cnblogs.com/livewithnorest/p/2868087.html
Copyright © 2011-2022 走看看