《unix环境高级编程》 读书笔记 (4)

发布时间:2024-12-21 02:18

阅读编程书籍,如《算法导论》和《JavaScript高级程序设计》。 #生活知识# #科技生活# #编程学习#

目录: http://blog.csdn.net/alex_my/article/details/39346381

system data files and infomation

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;

}

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

有以下函数可以操作这个文件:

#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;

}

网址:《unix环境高级编程》 读书笔记 (4) https://www.yuejiaxmz.com/news/view/529462

相关内容

读书笔记
《高老头》读书笔记(精选21篇)
《养花》读书笔记
心理学与生活读书笔记
亲子共读读书笔记(通用43篇)
【读书笔记】代码大全26章:代码优化技术
【读书笔记】林语堂
《幼儿园真谛》读书笔记
读书笔记:《生活黑客》
《生活的艺术》读书笔记

随便看看