apue第六章學習總結
1.關于陰影檔案與密碼
在密碼檔案當中,常見的字段有(以root為例):
root(使用者名):x(加密密碼):0(uid):0(gid):root(注釋字段):/root(使用者所在根目錄):/bin/bash(使用者的shell所在目錄)
注意:這裡的加密密碼隻是一個占位符号,真正的加密密碼存于陰影檔案當中,陰影密碼檔案不應是一般使用者可以讀取的。僅有少數幾個程式需要存取加密密碼,例如
login(1)
和
passwd(1)
,這些程式常常是設定使用者ID為root的程式。用了陰影密碼後,普通檔案
/etc/passwd
可由各使用者自由讀取。
在linux下,以下代碼會輸出加密密碼(從陰影密碼檔案中拉取):
#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;
}
2.編寫一個程式,它調用 uname
并輸出 utsname
結構中的所有字段,将該輸出與 uname -a
指令的輸出結果作比較。
uname
utsname
uname -a
本題難度并不大,注意記得函數指派給一個指向結構體的指針時記得向記憶體配置設定一塊空間,否則調用
uname()
函數時會失敗。
代碼如下:
#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;
}
3.編寫一個程式,擷取目前時間,并使用 strftime
将輸出結果轉換為類似于 date
指令的預設輸出。将環境變量TZ設定為不同的值,觀察輸出結果。
strftime
date
#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;
}