作業五 要實做出UNIX系統中
類似id,date 這兩個功能指令的程式
(一)myid
指令 id 是用來查詢任意人士的UID/GID
程式中使用 getpwnam(),getgrgid()等函式,
struct passwd *,struct group *等資料結構
撰寫程式 myid。 其中只要實現id的其中兩種功能
No1. ./myid username
列出目前使用者的:
1.user ID(uid)及其名稱(username)
2.group iID(gid)及其名稱(groupname)
3.其所屬group數目
No2. ./myid -P username
列出使用者的相關資料如下:
原理:
在UNIX系統中 使用者登入後
系統就必須取得該位使用者的相關資料
(屬於哪些group 以決定擁有哪些權限等)
這樣的user databse 在UNIX系統中
是以password file來作為儲存使用者資訊的檔案
password的資料結構為下:
Description | struct passwd member | POSIX.1 | FreeBSD 5.2.1 | Linux 2.4.22 | Mac OS X 10.3 | Solaris 9 |
---|---|---|---|---|---|---|
user name | char *pw_name | • | • | • | • | • |
encrypted password | char *pw_passwd | • | • | • | • | |
numerical user ID | uid_t pw_uid | • | • | • | • | • |
numerical group ID | gid_t pw_gid | • | • | • | • | • |
comment field | char *pw_gecos | • | • | • | • | |
initial working directory | char *pw_dir | • | • | • | • | • |
initial shell (user program) | char *pw_shell | • | • | • | • | • |
user access class | char *pw_class | • | • | |||
next time to change password | time_t pw_change | • | • | |||
account expiration time | time_t pw_expire | • | • |
*紅色為此次作業需用到的部份
而另一個與使用者相關的檔案就是Group File
裡面是存了有關group database的資料
其資料結構如下:
Description | struct group member | POSIX.1 | FreeBSD 5.2.1 | Linux 2.4.22 | Mac OS X 10.3 | Solaris 9 |
---|---|---|---|---|---|---|
group name | char *gr_name | • | • | • | • | • |
encrypted password | char *gr_passwd | • | • | • | • | |
numerical group ID | int gr_gid | • | • | • | • | • |
array of pointers to individual user names | char **gr_mem | • | • | • | • | • |
作法:
step 1: 檢查查詢的username是否存在於目前的系統中
我在這邊寫了一個exist_check(char* username)
先利用setpwent(); //rewind the passwd file
再與迴圈搭配 如果最後其中有與傳入的username相同的資料的話
就回傳Existflag=1 沒有相同的話就回傳Existflag=0
再用endpwent(); //close the passwd file
step 2: 依據輸入參數格式決定程式功能
myid需看依據輸入參數( -P)的有無還決定以哪種方式執行
若在exist_chexk確定有此username後
我們將此帳號的gid(由其password file取得)傳入getgrgid()這個函式
以取得此帳號是屬於哪些group(一個帳號可同時屬於不同的group)
的gourplist[ ]及其個數groupnum
假如是屬於No1.的用法 就跳入fun1(char* username) //function 1 (id username)
印出所需的資料
*此處要注意因為groupnum的不同 所以印出的排版要注意
ex:
b933040038@homework ~ $ id b933040038
uid=10072(b933040038) gid=10000(student) groups=10000(student) //印出部份
(以上資料內容皆可由struct passwd 取得)
No 2.的功能就比較簡單 就直接印出所有struct passwd的資料即可
(二)mydate
關於指令 date 是用來設定顯示目前系統時間
(a) 須使用 strftime()等函式,struct time *等資料結構撰寫程式 mydate。
(b) 這次作業 mydate 只需實作 date 的顯示目前時間的功能即可
範例如下:


原理:
在UNIX系統中 時間是由kernel所提供的calendar times
以Epoch:
00:00:00 January 1, 1970, Coordinated Universal Time (UTC)為基準
但這樣取得數字人類是看不懂且地球上的時區也不同
所以我們必須做對應的轉換 示意圖如下
作法:
這部份很簡單 所以直接用程式碼當說明
#include<stdio.h>
#include<time.h>
#include<sys/time.h>
#define BUFFSIZE 256
struct tm *mytime;
int main(void)
{
char buf[BUFFSIZE];
time_t ptr;
time(&ptr); //取得calendar times
mytime=localtime(&ptr); //取得broken times
strftime(buf,BUFFSIZE,"%a %b %e %T %Z %G",mytime);
/*strftime是將所需時間輸出格式以字元陣列的方式存入buf中
後面的參數代表不同意義*/
printf("%s",buf); //印出結果
return 0;
}