[單刷APUE系列]第六章——系統數據文件和信息

目錄

[單刷APUE系列]第一章——Unix基礎知識[1]
[單刷APUE系列]第一章——Unix基礎知識[2]
[單刷APUE系列]第二章——Unix標準及實現
[單刷APUE系列]第三章——文件I/O
[單刷APUE系列]第四章——文件和目錄[1]
[單刷APUE系列]第四章——文件和目錄[2]
[單刷APUE系列]第五章——標準I/O庫
[單刷APUE系列]第六章——系統數據文件和信息
[單刷APUE系列]第七章——進程環境
[單刷APUE系列]第八章——進程控制[1]
[單刷APUE系列]第八章——進程控制[2]
[單刷APUE系列]第九章——進程關係
[單刷APUE系列]第十章——信號[1]node

口令文件

使用過Unix系統的朋友應該知道/etc/passwd文件,這就是Unix系統口令文件,在POSIX1.x規範中規定Unix系統必須存在用戶數據庫,這些用戶數據庫裏每一個用戶都須要包含一些字段,具體須要查看<pwd.h>頭文件。shell

struct passwd {
        char    *pw_name;               /* user name */
        char    *pw_passwd;             /* encrypted password */
        uid_t   pw_uid;                 /* user uid */
        gid_t   pw_gid;                 /* user gid */
        __darwin_time_t pw_change;              /* password change time */
        char    *pw_class;              /* user access class */
        char    *pw_gecos;              /* Honeywell login info */
        char    *pw_dir;                /* home directory */
        char    *pw_shell;              /* default shell */
        __darwin_time_t pw_expire;              /* account expiration */
};

在不少Unix系統中,passwd是一個ASCII文件,每一行是一個用戶,而後每一個用戶都包含這些字段,字段之間使用冒號分隔,可是在蘋果系統中,則是使用opendirectory守護進程來存儲用戶數據庫等數據。
系統提供了兩個獲取口令文件項的函數數據庫

struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *login);

這兩個函數都會返回passwd結構體,並且須要注意的是,這個結構體指針其實是指向一塊靜態區域的指針,也就是說,不一樣經過保留指針來讓後面使用。segmentfault

struct passwd *getpwent(void);

void setpwent(void);
void endpwent(void);

getpwent函數則是一項一項讀取,而後將其以passwd結構體返回,很是適合須要讀取所有內容的狀況。setpwent和endpwent清理讀取的緩存,其中endpwent則是關閉全部的文件,當使用getpwent後必定要使用endpwent關閉文件。數組

陰影口令

在最初的Unix系統實現中,密碼是存放在/etc/passwd文件的第二個字段中,可是因爲有不少程序讀取這個文件,因此這個字段被專門移出來放在/etc/shadow中,一般狀況下,只有root權限才能讀取。在Solaris和Linux中,有一組函數用於訪問陰影口令文件,可是,很是遺憾的是,蘋果系統中沒有,因此這裏也就只能講一講,而不能列出實際的代碼。緩存

組文件

struct group {
        char    *gr_name;               /* [XBD] group name */
        char    *gr_passwd;             /* [???] group password */
        gid_t   gr_gid;                 /* [XBD] group id */
        char    **gr_mem;               /* [XBD] group members */
};

上面是蘋果系統定義的group結構體運維

struct group *getgrgid(gid_t gid);
struct group *getgrnam(const char *name);

struct group *getgrent(void);
void setgrent(void);
void endgrent(void);

就如同口令文件的函數同樣,上面的函數用法也是同樣的。函數

附屬組ID

在早期Unix系統實現中,是不存在附屬組的。直到後來BSD的一個版本引入了附屬組ID的概念,這樣在權限檢查的時候也須要檢查附屬組ID的權限ui

int getgroups(int gidsetsize, gid_t grouplist[]);

int setgroups(int ngroups, const gid_t *gidset);

int initgroups(const char *name, int basegid);

getgroups函數將進程所屬用戶的附屬組ID放入grouplist參數中,groupsize參數用於肯定放入的大小,可是實際上,咱們能夠將groupsize設置爲0,而後函數會返回實際的附屬組個數,而後就能夠很方便的分配grouplist數組,用不着去猜想究竟應該分配多少。
setgroups是一個root權限操做,用於爲進程設置附屬組ID。
initgroups是一系列操做的集合,實際上用到的機會極少,若是有須要的朋友能夠自行觀看系統手冊。this

其餘數據文件

除了上面講到的兩個文件之外,系統還有不少其餘的文件,可是基本上都是提供了一樣的接口(get,set,end),並且和前面的用法基本同樣,因此這裏也再也不講解。

登陸帳戶記錄

在實際的運維中,常常會須要查看用戶的登陸日誌,因此係統也有相關的數據文件和接口函數用於開發使用。
原著中講解了utemp結構體的內容,這裏再也不多講,可是在蘋果系統中,實際上已經被utempx等結構體所取代

struct utmpx {
        char ut_user[_UTX_USERSIZE];    /* login name */
        char ut_id[_UTX_IDSIZE];        /* id */
        char ut_line[_UTX_LINESIZE];    /* tty name */
        pid_t ut_pid;                   /* process id creating the entry */
        short ut_type;                  /* type of this entry */
        struct timeval ut_tv;           /* time entry was created */
        char ut_host[_UTX_HOSTSIZE];    /* host name */
        __uint32_t ut_pad[16];          /* reserved for future use */
};

struct lastlogx {
        struct timeval ll_tv;           /* time entry was created */
        char ll_line[_UTX_LINESIZE];    /* tty name */
        char ll_host[_UTX_HOSTSIZE];    /* host name */
};

其實,不光是蘋果系統,其餘的Unix系統的字段也已經被修改擴充了,並且其實這個並不重要,因此只須要了解便可。

系統標識

POSIX定義了uname函數,用於返回主機和操做系統相關的信息,uname命令就是使用了這個函數。

int uname(struct utsname *name);

struct  utsname {
        char    sysname[_SYS_NAMELEN];  /* [XSI] Name of OS */
        char    nodename[_SYS_NAMELEN]; /* [XSI] Name of this network node */
        char    release[_SYS_NAMELEN];  /* [XSI] Release level */
        char    version[_SYS_NAMELEN];  /* [XSI] Version level */
        char    machine[_SYS_NAMELEN];  /* [XSI] Hardware type */
};

全部的成員都是以null字節結尾,而且BSD派生系統也提供了gethostname函數

int gethostname(char *name, size_t namelen);

實際上還有一個sethostname函數,可是這裏也很少講,除此之外,上面的一些函數實際上有一些已經被移到標準C庫中了,因此也能做爲跨平臺開發使用。

日期和時間

Unix系統都使用的是Unix時間戳,也就是UTC時間1970年1月1日0時0分0秒以來的秒數,在前面咱們提到過它,這個就是日曆時間,而且是使用time_t類型存儲的。

time_t time(time_t *tloc);

time函數就是很簡單的獲取日曆時間,在通常的狀況下,都是傳入null而後得到函數返回值來使用。原著中也講到了指定時間的獲取,可是很是不幸,蘋果系統又沒有這些方法,因此這裏也只能不說起了。

相關文章
相關標籤/搜索