linux獲取各種進程類型的信息

1 password file

終端上輸入cat /etc/passwd
可以看見很多相關信息。

也可以通過以下函數:

#include <sys/types.h>
#include <pwd.h>

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

int getpwnam_r(const char* name, struct passwd* pwd, char* buf, size_t buflen, struct passwd** result);
int getpwuid_r(uid_t uid, struct passwd* pwd, char* buf, size_t buflen, struct passwd** result);

結構體passwd(<pwd.h>):

struct passwd 
{
     char*     pw_name;       /* username */
     char*     pw_passwd;     /* user password */
     uid_t     pw_uid;        /* user ID */
     gid_t     pw_gid;        /* group ID */
     char*     pw_gecos;      /* user information */
     char*     pw_dir;        /* home directory */
     char*     pw_shell;      /* shell program */
};

如果不能理解每個成員的意思,可以通過man 5 passwd查閱。

getpwuid和getpwnam的程序用例:

#include <stdio.h>
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>

static void PrintfPwd(const passwd* pwdInfo)
{
     if(!pwdInfo)
          return;

     printf("name: \t%s\n", pwdInfo->pw_name);
     printf("passwd: \t%s\n", pwdInfo->pw_passwd);
     printf("uid: \t%d\n", pwdInfo->pw_uid);
     printf("gid: \t%d\n", pwdInfo->pw_gid);
     printf("gecos: \t%s\n", pwdInfo->pw_gecos);
     printf("dir: \t%s\n", pwdInfo->pw_dir);
     printf("shell: \t\%s\n", pwdInfo->pw_shell);
}

int main(int argc, char* argv[])
{
     printf("test getpwuid: \n");
     uid_t uid = getuid();
     printf("uid: %d\n", uid);

     // test getpwuid
     struct passwd* pwdInfo = getpwuid(uid);
     if(!pwdInfo)
          return 1;

     PrintfPwd(pwdInfo);

     // test getpwnam
     printf("\n\ntest getpwnam: \n");
     struct passwd* pwdInfo2 = getpwnam(pwdInfo->pw_name);
     PrintfPwd(pwdInfo2);

     return 0;
}


getpwuid_r用例:

#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#include <unistd.h>
#include <errno.h>

static void PrintfPwd(const passwd* pwdInfo)
{
     if(!pwdInfo)
          return;
     printf("name: \t%s\n", pwdInfo->pw_name);
     printf("passwd: \t%s\n", pwdInfo->pw_passwd);
     printf("uid: \t%d\n", pwdInfo->pw_uid);
     printf("gid: \t%d\n", pwdInfo->pw_gid);
     printf("gecos: \t%s\n", pwdInfo->pw_gecos);
     printf("dir: \t%s\n", pwdInfo->pw_dir);
     printf("shell: \t\%s\n", pwdInfo->pw_shell);
}


int main(int argc, char* argv[])
{
     uid_t uid = getuid();

     size_t len = sysconf(_SC_GETPW_R_SIZE_MAX);
     if(len == -1)
          len = 16384;

     char* buffer = new char[len];
     if(!buffer)
     {
          printf("buffer create failed. error[%d]\n", errno);
          return 1;
     }

     struct passwd pwd;
     struct passwd* result = NULL;

     int ret = getpwuid_r(uid, &pwd, buffer, len, &result);
     if(!result)
     {
          printf("getpwuid failed. ret[%d]\n", ret);
          return 1;
     }

     printf("----------pwd---------- \n");
     PrintfPwd(&pwd);

     printf("\n\n----------result----------\n");
     PrintfPwd(result);

     printf("\n\n----------buffer----------\n");
     printf("buffer: %s\n", buffer);

     return 0;
}

以下三個函數與讀取/etc/passwd相關:

#include <sys/types.h>
#include <pwd.h>

struct passwd* getpwent(void);
void setpwent(void);
void endpwent(void);

getpwent: 獲取passwd文件中的一個口令,嚴格的說,是獲取下一個口令
setpwent: 將獲取口令重置到第一個
endpwent: 關閉由getpwent打開的文件

程序用例:

#include <stdio.h>
#include <pwd.h>

int main(int argc, char* argv[])
{
     // 爲了測試方便,最多隻打印10個口令信息
     struct passwd* pwd;
     // 設置從頭開始讀取
     setpwent();
     int n = 0;
     while((pwd = getpwent()) != NULL)
     {
          printf("name: %s \t uid: %d\n", pwd->pw_name, pwd->pw_uid);
          if(++n >= 10)
               break;
     }

     endpwent();

     return 0;
}



2 shadow passwords

看着名字就知道它藏的好深。

有以下函數可以操作這個文件:

#include <shadow.h>

struct spwd* getspnam(const char* name);
struct spwd* getspent(void);
void setspent(void);
void endspent(void);

struct spwd* fgetspent(FILE* fp);
struct spwd* sgetspent(const char* s);

int putspent(struct spwd* p, FILE* fp);
int lckpwdf(void);
int ulckpwdf(void);

/* GNU extension */
#include <shadow.h>

int getspent_r(struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp);
int getspnam_r(const char* name, struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp);
int fgetspent_r(FILE* fp, struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp);
int sgetspent_r(const char* s, struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp);

其中的struct spwd定義如下:

struct spwd 
{
     char* sp_namp;     /* Login name */
     char* sp_pwdp;     /* Encrypted password */
     long  sp_lstchg;   /* Date of last change
                           (measured in days since
                           1970-01-01 00:00:00 +0000 (UTC)) */
     long  sp_min;      /* Min # of days between changes */
     long  sp_max;      /* Max # of days between changes */
     long  sp_warn;     /* # of days before password expires
                           to warn user to change it */
     long  sp_inact;    /* # of days after password expires
                           until account is disabled */
     long  sp_expire;   /* Date when account expires
                           (measured in days since
                           1970-01-01 00:00:00 +0000 (UTC)) */
     unsigned long sp_flag;  /* Reserved */
};

getspnam程序用例:

#include <stdio.h>
#include <shadow.h>
#include <errno.h>
#include <string.h>

int main(int argc, char* argv[])
{
     struct spwd* pwd = getspnam("alex_my");
     if(!pwd)
     {
          printf("getspnam failed, error: [%d] [%s]\n", errno, strerror(errno));
          return 1;
     }

     printf("name: %s\t password: %s\n", pwd->sp_namp, pwd->sp_pwdp);


     return 0;
}

如果在普通賬號下運行,就會發生錯誤,因爲讀取文件的權限不夠。



3 group file

位於/etc/group

有以下函數可以操作:

#include <sys/types.h>
#include <grp.h>

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

int getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result);
int getgrgid_r(gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result);

用法可以參考passwd file

用戶在登陸的時候,就會獲取到group ID,屬於某一個group,可以通過命令來改變所屬的組。但總體來說不方便。
於是,出現了supplementary group IDs(附加組ID)。


4 獲取本地主機名

#include <unistd.h>

int gethostname(char* name, size_t namelen);

#include <stdio.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
     char name[256] = { 0 };
     gethostname(name, sizeof(name));
     printf("name: %s\n", name);

     return 0;
}
發佈了8 篇原創文章 · 獲贊 32 · 訪問量 30萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章