码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-09-15 17:48:59      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   使用   ar   for   

近来读书,做些笔记,来年好翻翻。
本文所使用的操作系统为 CentOS7.0,如果不想装双系统的可以装虚拟机,可以参考这里:
http://blog.csdn.net/alex_my/article/details/38142229

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



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

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

标签:style   blog   http   color   io   os   使用   ar   for   

原文地址:http://blog.csdn.net/alex_my/article/details/39294513

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!