Chinaunix首页 | 论坛 | 博客
  • 博客访问: 253515
  • 博文数量: 44
  • 博客积分: 1052
  • 博客等级: 少尉
  • 技术积分: 742
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-17 16:51
文章分类

全部博文(44)

文章存档

2013年(7)

2012年(14)

2011年(23)

分类: LINUX

2011-02-22 11:16:34

     悲剧!昨天写了一部分,忘了存了。

     首先讲述/etc/passwd文件的相关内容。
     结构体struct passwd:
     char    *pw_name:用户名
     char    *pw_passwd:加密密码
     uid_t    pw_uid:用户数字ID
     gid_t    pw_gid:组数字ID
     char    *pw_gecos:备注域
     char    *pw_dir:初始工作目录
     char    *pw_shell:初始shell

     /etc/passwd的内容举例:
     root:x:0:0:root:/root:/bin/bash
     squid:x:23:23::/var/spool/squid:/dev/null
     nobody:x:65534:65534:Nobody:/home:/bin/sh
     说明:
     (1):/etc/passwd中必有root用户。
     (2):初始shell域为/dev/null,/dev/false,/dev/true时,该用户不能登录系统。
     (3):nobody的UID和GID均为65534,表明只有那些能被所有用户访问的文件,nobody才能访问。

     与该文件相关的函数:
  1. #include <pwd.h>
  2. struct passwd *getpwuid(uid_t uid);
  3. struct passwd *getpwnam(const char *name);
  4.           // return: pointer if OK, NULL on error
  5. struct passwd *getpwent(void);
  6.           // return: pointer if OK, NULL on error or end of file
  7. void setpwent(void);
  8. void endpwent(void);
     getpwuid通过UID来得到struct passwd。getpwnam通过用户名来得到struct passwd。getpwent返回/etc/passwd文件中的下一项。setpwent将文件位置设为文件开头,endpwent关闭文件。

     下面讲述关于/etc/shadow文件,该文件每一项为一行,一项中有9个域。
     结构体struct spwd:
     char  *sp_namp:用户名
     char  *sp_pwdp:加密密码
     int     sp_lstchg:
     int     sp_min:
     int     sp_max:
     int     sp_warn:
     int     sp_inact:
     int     sp_expire:
     unsigned int  sp_flag:

     具体的可以用man 5 shadow查看。/etc/shadow文件只能由root用户查看更改。
     与该文件相关的函数:
  1. #include <shadow.h>

  2. struct spwd *getspnam(const char *name);
  3. struct spwd *getspent(void);
  4.             // return: pointer if OK, NULL on error
  5. void setspent(void);
  6. void endspent(void);
     getspnam根据用户名得到对应的spwd。getspent,setspent,endspent的作用同/etc/passwd的那组函数。

     /etc/group文件
     struct group:
     char  *gr_name :组名称
     char  *gr_passwd:组密码
     int     gr_gid :组数字ID
     char  **gr_mem :指向单个用户名的指针组成的数组。最后用一个NULL指针标识结束。
     关于这个结构体唯一不明白的就是组密码是啥时候用到的?
     关于group也有相应的一组函数:
  1. #include <grp.h>
  2. struct group *getgrgid(gid_t gid);
  3. struct group *getgrnam(const char *name);
  4.              // return: pointer if OK, NULL on error
  5. struct group *getgrent(void);
  6.              // return: pointer if OK, NULL on error or end of file
  7. void setgrent(void);
  8. void endgrent(void);

     supplementary group IDs  (我称这为附加组ID)。用意大概是一个用户可以同时属于多个组。
     下面是一些与之相关的函数:
  1. #include <unistd.h>

  2. int getgroups(int gidsetsize, gid_t grouplist[]);
  3.                  // return number of supplementary group IDs if OK, -1 on error

  4. #include <grp.h>    // on linux
  5. #include <unistd.h> // on freebsd, mac, solaris
  6. int setgroups(int ngroups, const gid_t grouplist[]);

  7. #include <grp.h>    // on linux and solaris
  8. #include <unistd.h> // on freebsd and mac
  9. int initgroups(const char *username, gid_t basegid);
  10.                  // return 0 if OK, -1 on error
     函数getgroups将supplementary group IDs填入grouplist数组,最多只能填gidsetsize个,返回填入的个数。如果gidsetsize的值为0,该函数只返回supplementary group IDs的个数。函数setgroups用来设置用户的supplementary group,ngroups用于指定个数,grouplist数组用来指明GID,ngroups不能超过NGROUPS_MAX,该函数要由超级用户来调用。函数initgroups读取整个group文件,获取username的组关系,然后调用setgroups来设定,因此initgroups也要超级用户才能使用。

     其他的数据文件。
     Linux中还有很多其他数据文件,比如/etc/services, /etc/protocols, /etc/networks等等。但它们的接口函数却基本和passwd,group的类似。都由一个get函数来读取每一项,返回指向对应结构体的指针。有一个set函数来设置文件位置为文件开头。有一个end函数来关闭文件。

     登录账号。
     有两个文件用来记录登录相关的信息。
     utmp文件:记录当前登录到系统的用户名。/var/run/utmp
     wtmp文件:保存所有的登录和注销记录。/var/log/wtmp
     struct utmp{
          char  ut_line[8];
          char  ut_name[8];
          long  ut_time;
     }
     登录时,login程序会填写一个该结构体并存入utmp文件,并添加在wtmp的末尾。退出登录时,utmp中的数据由init程序擦除,但在wtmp末尾添加一个结构体数据。命令who用来读取utmp文件并打印信息,而last命令则读取wtmp文件。

     system identification
     函数uname用于返回当前系统的信息。
  1. #include <sys/utsname.h>
  2. int uname(struct utsname *name);
  3.           // return: non-negative value if OK, -1 on error

  4. struct utsname {
  5.      char sysname[];
  6.      char nodename[];
  7.      char release[];
  8.      char version[];
  9.      char machine[];
  10. };
     一般系统会提供uname命令来打印这些信息。也可以 查看/proc/sys/kernel/{ostype, hostname, osrelease, version}这些文件的内容来获得。
     系统也提供了函数gethostname来获取hostname。
  1. #include <unistd.h>
  2. int gethostname(char *name, int namelen);
     hostname的最大长度由宏HOST_NAME_MAX来指定。


     时间和日期
     系统提供的最基本的时间服务是类型为time_t的日历时间(calendar times),它表示从1970年1月1日 00:00:00到现在(UTC时间)经过的秒数。
  1. #include <time.h>
  2. time_t time(time_t *calptr);
  3.           // return: value of time if OK, -1 on error

  4. #include <sys/time.h>
  5. int gettimeofday(struct timeval *restrict tp, void *restrict tzp);
  6.           // return: 0 always

  7. struct timeval{
  8.      time_t tv_sec; /* seconds */
  9.      long tv_usec; /* microseconds */
  10. };
     gettimeofday能返回更精细的时间,其中tzp的唯一合法的值为NULL。
     (书中只是简单列出了time.h中声明的一些函数,并没讲什么特别的东西。唯一较好的就是书中的那副图了,这书中的图总能让人看着神清气爽。哈哈)

     
     
  1. #include <time.h>

  2. struct tm{
  3.      int tm_sec;
  4.      int tm_min;
  5.      int tm_hour;
  6.      int tm_mday;
  7.      int tm_mon;
  8.      int tm_year;
  9.      int tm_wday;
  10.      int tm_yday;
  11.      int tm_isdst;
  12. }

  13. struct tm *gmtime(const time_t *calptr);
  14. struct tm *localtime(const time *calptr);
  15. time_t mktime(struct tm *tmptr);
  16. char * asctime(const struct tm *tmptr);
  17. char * ctime(const time_t *calptr);
  18. size_t strftime(char *restrict buf, size_t maxsize, const char *restrict format, const struct tm *restrict tmptr);
     这些都不加说明了,主要是区分什么时候是本地时间,什么时候是UTC时间。

未完待续...      (过段时间加个自己写的小程序进来)
阅读(1627) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~