1. 程式人生 > >UNIX環境高階程式設計(三) 第六章

UNIX環境高階程式設計(三) 第六章

6 系統資料檔案和資訊

6.2 口令檔案

#include <pwd.h>
struct passwd *getpwuid(uid_t uid); /* 檢視使用者登入名 */
struct passwd *getpwnam(const char *name); /* 檢視使用者ID */
    return: pointer; error: NULL

struct passwd *getpwent(void); /* 檢視整個口令檔案,返回口令檔案中的下一個記錄項,到達最後返回NULL */
    return: pointer; error: NULL
void setpwent(void
); /* 反繞它所使用的檔案 */ void endpwent(void); /* 關閉這些檔案 */ struct passwd { char * pw_name; /* Username, POSIX.1 */ char * pw_passwd; /* Password */ __uid_t pw_uid; /* User ID, POSIX.1 */ __gid_t pw_gid; /* Group ID, POSIX.1 */ char * pw_gecos; /* Real Name or Comment field */ char * pw_dir; /* Home directory, POSIX.1 */
char * pw_shell; /* Shell Program, POSIX.1 */ };

1.通常有一個登入項,其使用者名稱為root,其使用者ID是0(超級使用者). 2.加密口令欄位包含了經單向密碼演算法處理過的使用者口令副本. 3.口令檔案中的某些欄位可能為空.(如果密碼口令為空,意味著沒有密碼) 4.支援finger命令的某些unix系統支援註釋欄位中的附加資訊.

6.3 陰影口令檔案

#include <shadow.h>
struct spwd *getspnam(const char *name);
struct spwd *getspend(void
); retrun: struct pointer; error: NULL. void setspend(void); void endspend(void); struct spwd { char *sp_namp; /* Login name */ char *sp_pwdp; /* Encrypted password */ long int sp_lstchg; /* Date of last change */ long int sp_min; /* Minimum number of days between changes */ long int sp_max; /* Maximum number of days between changes */ long int sp_warn; /* Number of days to warn user to change the password */ long int sp_inact; /* Number of days the account may be inactive */ long int sp_expire; /* Number of days since 1970-01-01 until account expires */ unsigned long int sp_flag; /* Reserved */ };

對unix口令通常使用的加密演算法是單向演算法.給出一個密碼口令,找不到一種演算法可以將其反變換到普通文字口令(普通文字口令是在Password:提示後鍵入的口令).但是可以猜測,比如用跟使用者相關的事物進行猜測密碼然後經單向演算法加密形成,這樣就存在了洩密的可能,所以要避免. 為使企圖這樣做的人難以獲得加密口令,某些系統將加密口令存放在另一個通常稱為陰影口令(shadow password)的檔案中.

6.4 組檔案

#include <grp.h>
struct group *getgrgid(gid_t gid);
struct group *getgrnam(const char *name);
    return: struct pointer; error: NULL.

struct group{ 
    char *gr_name; /* Group name */ 
    char *gr_passwd; /* password */ 
    __gid_t gr_gid; /* Group ID */ 
    char **gr_mem; /* Member list */
};

struct group *getgrent(void);
    return: struct pointer; error: NULL.
void setgrent(void);
void endgrent(void);

包含組名,加密口令,數字組ID,指向各使用者名稱指標的陣列.

6.5 附屬組ID

#include <unistd.h>
int getgroups(int gidsetsize, gid_t grouplist[]);
    return: groupID's quantity; error: -1.

#include <grp.h> /* on Linux */
#include <unistd.h> /* On FreeBSD, Mac OS X, and Solaris */
int setgroups(int ngroups, const git_t grouplist[]);

#include <grp.h> /* On Linux and Solaris */
#include <unistd.h> /* On FreeBSD and Mac OS X */
int initgroups(const char *username, gid_t basegid);
    return: 0; error: -1.

setgroups函式可由超級使用者呼叫以便為呼叫程序設定新增組ID表. grouplist是組ID陣列,而ngroups說明了陣列中的元素數.

6.6 其他資料檔案

已提到過兩個系統資料檔案–口令檔案和組檔案. 記錄各網路伺服器所提供的服務的資料檔案:/etc/services 記錄協議資訊的資料檔案:/etc/protocols 記錄網路資訊的資料檔案:/etc/networks 主機:/etc/hosts

6.7 登入會計

大多數unix系統都提供下列兩個資料檔案: utmp:它記錄當前登入進系統的各個使用者 wtmp:它跟蹤各個登入和登出事件

6.8 系統標識

uname函式,它返回與主機和作業系統有關的資訊.

#include <sys/utsname.h>
int uname(struct utsname *name);
    return: !0; error: -1.
#include <unistd.h>
int gethostname(char *name, int namelen);
    return: 0; error: -1.

struct utsname {
    char sysname[]; // name of the OS.
    char nodename[]; // name of this node.
    char release[]; // current release of OS.
    char version[]; //current version of this release.
    char  machine[]; // name of hardware type.
};

6.9 時間和日期例程

#include <time.h>
time_t time(time_t *calptr); //獲取當前的時間和日期
    return: time value; error: -1.
struct tm *gmtime(const time_t *calptr);//將日曆時間轉換協調統一時間的年,月,日,時,分,秒,週日分解結構。
struct tm *localtime(const time_t *calptr);//將日曆時間轉換成本地時間(考慮本地時區和夏令時標誌)
    return: 指向分解的tm結構的指標; error: NULL.
time_t mktime(struct tm *tmptr); //以本地時間的年月日等作為引數,轉變為time_t值
    return: time_t value; error: -1.

下面strftime函式是一個類似於printf的時間值函式,可通過可用的多個引數來制定產生的字串.
size_t strftime(char *restrict buf, size_t maxsize, const char *restrict format, const struct tm *restrict tmptr);
    return: 若有空間,返回存入陣列的字元數,error: 0.
size_t strftime_l(char *restrict buf, size_t maxsize, const char *restrict format, const struct tm *restrict tmptr, locale_t locale);
    return: 若有空間,返回存入陣列的字元數,error: 0.

struct tm {
    int tm_sec; //seconds after the minute:[0-60]
    int tm_min; //minutes after the hour:[0-59]
    int tm_hour;//hours after the midnight:[0-23]
    int tm_mday; //day of the month:[1-31]
    int tm_mon; //months since January:[0-11]
    int tm_year; // years since 1900
    int tm_wday; // days since sunday:[0-6]
    int tm_yday; // days since January 1: [0-365]
    int tm_isdst; // daylight saving time flag: <0, 0,>0
}

#include <sys/time.h>
int clock_gettime(clockid_t clock_id, struct timespec *tsp); // 獲取指定時鐘的時間,精度比time高
    return: 0; error: -1.
int clock_getres(clockid_t clock_id, struct timespec *tsp); //將tsp指向的timespec結構初始化為clock_id引數對應的時鐘精度
    return: 0; error: -1.
int clock_settime(clockid_t clock_id, const struct tiemsepc *tsp); // 對特定時鐘設定時間
    return: 0; error: -1.
int gettimeofday(struct timeval *restrict tp, void *restrict tzp); //函式已棄用,提供了比time更高的精度(微秒級)
    return: 0