在口令文件當中,常見的字段有(以root爲例):node
root(用戶名):x(加密口令):0(uid):0(gid):root(註釋字段):/root(用戶所在根目錄):/bin/bash(用戶的shell所在目錄)
注意:這裏的加密口令只是一個佔位符號,真正的加密口令存於陰影文件當中,陰影口令文件不該是通常用戶能夠讀取的。僅有少數幾個程序須要存取加密口令,例如login(1)
和passwd(1)
,這些程序經常是設置用戶ID爲root的程序。用了陰影口令後,普通文件/etc/passwd
可由各用戶自由讀取。linux
在linux下,如下代碼會輸出加密口令(從陰影口令文件中拉取):shell
#include "apue.h" #include <shadow.h> int main(){ struct spwd *ptr; if((ptr = getspnam("sysublackbear")) == NULL){ err_sys("getspnam error"); } printf("sp_pwdp = %s\n", ptr->sp_pwdp == NULL || ptr->sp_pwdp[0] == 0 ? "(null)":ptr->sp_pwdp); return 0; }
uname
並輸出utsname
結構中的全部字段,將該輸出與uname -a
命令的輸出結果做比較。本題難度並不大,注意記得函數賦值給一個指向結構體的指針時記得向內存分配一塊空間,不然調用uname()
函數時會失敗。數組
代碼以下:bash
#include "apue.h" #include <sys/utsname.h> int main() { struct utsname* ptr; //在調用函數uname時先開闢一塊新的空間,若是將指針設爲NULL,下面函數不會運行成功,由於系統沒有爲其開闢內存空間 ptr = (struct utsname*)malloc(sizeof(struct utsname)); int temp; if(temp = uname(ptr) == -1){ err_sys("uname error"); } //寫成uname -a 的形式 printf("%s %s %s %s %s\n",ptr->sysname == NULL ? "(NULL)" : ptr->sysname, ptr->nodename == NULL ? "(NULL)" : ptr->nodename, ptr->release == NULL ? "(NULL)" : ptr->release, ptr->version == NULL ? "(NULL)" : ptr->version, ptr->machine == NULL ? "(NULL)" : ptr->machine ); return 0; }
strftime
將輸出結果轉換爲相似於date
命令的默認輸出。將環境變量TZ設置爲不一樣的值,觀察輸出結果。代碼以下:函數
#include "apue.h" #include <time.h> int main() { time_t caltime; struct tm *tm; char line[MAXLINE]; //獲取當前時間 if((caltime = time(NULL)) == -1){ err_sys("time error"); } //將當前時間轉換爲對應的日曆時間,存到tm結構體中 if((tm = localtime(&caltime)) == NULL){ err_sys("localtime error"); } //再將日曆時間打印成date的格式 if(strftime(line,MAXLINE,"%a %b %d %X %Z %Y\n",tm) == 0){ err_sys("strftime error"); } //打印字符串(將字符數組輸出到stdout流當中) fputs(line,stdout); return 0; }