您的位置:首页 > 产品设计 > UI/UE

《APUE》笔记-第六章-系统数据文件和信息

2016-11-01 19:01 411 查看

1.口令文件

口令文件,即Unix系统用户数据库,存储在/etc/passwd中,是一个ASCII文件,包含的字段信息在<pwd.h>定义的passwd数据结构中。  

pwd.h文件所在位置:/usr/include/pwd.h
struct passwd
{
      char *pw_name;
      char *pw_passwd;
      uid_t uid;
      gid_t gid;
      char *pw_gecos;
      char *pw_dir;
      char *pw_shell;
};
分别根据用户ID和用户名获取口令文件函数:
struct passwd *getpwuid(uid_t uid);   //根据用户ID
struct passwd *getpwnam(const char *name);  //根据用户名


查看整个口令文件并遍历:
struct passwd *getpwent(void); //返回口令文件中的下一个记录项
void setpwent(void); //反绕文件,从文件头开始
void endpwent(void); //关闭文件


根据uid取得记录项、取下一记录项、遍历文件打印用户名;程序如下:
#include <stdio.h>
#include <pwd.h>

int main()
{
struct passwd *ppwd = NULL;
setpwent();
if ((ppwd = getpwuid(500)) != NULL)
{
printf("getpwuid() ok\n");
printf("name: %s  ", ppwd->pw_name);
printf("passwd: %s  ", ppwd->pw_passwd);
printf("uid: %d  ", ppwd->pw_uid);
printf("gid: %d  ", ppwd->pw_gid);
printf("gecos: %s  ", ppwd->pw_name);
printf("director: %s  ", ppwd->pw_dir);
printf("shell: %s  \n", ppwd->pw_shell);
}
endpwent();
struct passwd *ppwd2 = NULL;
setpwent();
if ((ppwd2 = getpwent()) != NULL)
{
printf("getpwent() ok\n");
printf("name: %s  ", ppwd2->pw_name);
printf("passwd: %s  ", ppwd2->pw_passwd);
printf("uid: %d  ", ppwd2->pw_uid);
printf("gid: %d  ", ppwd2->pw_gid);
printf("gecos: %s  ", ppwd->pw_name);
printf("director: %s  ", ppwd->pw_dir);
printf("shell: %s  \n", ppwd->pw_shell);
}
endpwent();

setpwent();
printf("\nprint all user's name:\n ");
while ((ppwd = getpwent()) != NULL)
{
printf("%s ", ppwd->pw_name);
}
printf("\n");
endpwent();

return 0;
}
结果:



应在开始位置调用setpwent(),结束后调用endpwent()关闭文件

2.阴影口令

/etc/passwd文件,任何用户都可以读,密码不安全,所以需要将密码单独放到阴影口令中。只有超级用户(root)才能调用访问阴影文件的函数。阴影文件位于/etc/shadow文件中

#include <shadow.h>

struct spwd 

{
    char *sp_namp;     /* 登录名 */
    char *sp_pwdp;     /* 加密口令 */
    long  sp_lstchg;   /* 上次更改口令以来经过的时间 (measured in days since 1970-01-01 00:00:00 +0000 (UTC)) */
    long  sp_min;      /* 经多少天以后允许更改*/
    long  sp_max;      /* 要求更改尚余天数 */
    long  sp_warn;     /* 超期警告天数 */
    long  sp_inact;    /* 账户不活动之前尚余天数 */
    long  sp_expire;   /* 账户超期天数 */
    unsigned long sp_flag;  /* 保留 */
};


struct spwd *getspnam(const char *name);

struct spwd *getspent(void);

void setspent(void);

void endspent(void);

练习程序如下:
#include <stdio.h>
#include <shadow.h>

int main()
{
struct spwd *pspwd = NULL;
setspent();
if ((pspwd = getspnam("zxin")) != NULL)
{
printf("getspnam() ok\n");
printf("name: %s  ", pspwd->sp_namp);
printf("passwd: %s  ", pspwd->sp_pwdp);
}
endspent();

setspent();
printf("\nprint all user's name:\n ");
while ((pspwd = getspent()) != NULL)
{
printf("%s ", pspwd->sp_namp);
}
printf("\n");
endspent();

return 0;
}
结果:



分析:root账户才能执行这些函数

3.组文件

/etc/group  Unix组文件(组数据库) <grp.h>头文件 struct grp结构
#include <grp.h>
struct group 
{

    char   *gr_name;       /* group name */

    char   *gr_passwd;     /* group password */

    gid_t   gr_gid;        /* group ID */

    char  **gr_mem;        /*指向各用户名指针的数组*/

};


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

搜索整个文件组函数:
struct group *getgrent(void);
void setgrent(void);
void endgrent(void);


写个程序,输出组名和组id
#include <stdio.h>
#include <grp.h>

int main()
{
struct group *pgrp = NULL;
setgrent();
while ((pgrp = getgrent()) != NULL)
{
printf("group name: %s,         group id: %d\n", pgrp->gr_name, pgrp->gr_gid);
}
endgrent();
return 0;
}
结果如下:




4.附属组

我们不仅可以属于口令文件记录项中组ID所对应的组,也可属于至多16个另外的组。文件访问权限检查相应的被修改为:不仅将进程的有效组ID与文件组ID相比较,而且也将所有附属组ID与文件的组ID进行比较。
优点:不必再显示经常更改组,一个用户会参与多个项目,因此,也就要同时属于多个组
获取和设置组ID:
#include <unistd.h>
#include <grp.h>
int getgroups(int gidsetsize, gid_t grouplist[]);//获取进程个附属组ID,到grouplist[]中,最多gidsetsize个
int setgroups(int ngroups, const gid_t grouplist[]);//由超级用户调用,为调用进程设置附属组ID表
int initgroups(const char *username, gid_t
basegid);//调用setgroups,确定其组的成员关系,只有超级用户才能调用此函数

5.其他数据文件

 其他数据文件  除了口令文件和组文件外,Linux也使用很多其他文件,一般情况下,这些文件都至少支持三个函数:
(1)get函数:读文件中的下一个记录项。
(2)set函数:将文件偏移量设置到文件起始处。
(3)end函数:关闭系统文件。
  如果该文件支持关键字检索,例如口令文件支持基于用户名和用户ID的检索,因此实现了接口getpwnam和getpwuid函数,就会支持相应的函数。



6.系统标识

#include <sys/utsname.h>
int uname(struct utsname *name);//返回与主机和操作系统有关的信息
[b]返回值:成功,非负;失败,-1
[/b]
 struct utsname
{
        char sysname[];/* name of the operating system */
        char nodename[];/* name of this node */
        char release[];/* current release of operating system */
        char version[];/* current version of this release */
        char machine[];/* name of hardware type */
};

程序,返回主机和系统信息:
#include <stdio.h>
#include <sys/utsname.h>

int main()
{
struct utsname puts;
if (uname(&puts) == -1)
{
printf("uname() error\n");
exit(-1);
}
printf("system name: %s\n", puts.sysname);
printf("system nodename: %s\n", puts.nodename);
printf("system release: %s\n", puts.release);
printf("system version: %s\n", puts.version);
printf("system machine: %s\n", puts.machine);
return 0;
}
结果:



7.时间相关

参考:
http://www.cnblogs.com/Anker/archive/2012/12/15/2819038.html

    时间和日期,Unix内核提供的基本时间服务是计算自国际标准时间公元1970年1月1日00:00:00以来经过的秒数,基本数据类型是time_t,称为日历时间,包括时间和日期,将时间和日期作为一个量值进行保存。类型定义如下:

#ifndef __TIME_T

#define __TIME_T     /* 避免重复定义 time_t */

typedef long     time_t;    /* 时间值time_t 为长整型的别名*/

#endif
#include <time.h>

time_t time(time_t *t); 
//返回当前时间及日期


#include <sys/time.h>

struct tm *gmtime(const
time_t *timep);  //转换为国际标准时间
struct tm *localtime(const time_t *timep); //转换为本地时间


返回自1970.01.01经过的秒数、返回当前国际标准时间、返回本地时间,程序如下:
#include <stdio.h>
#include <time.h>

int main()
{
time_t now;
now = time(&now);
printf("seconds from 1970.01.01 is %ld\n", now);
struct tm *ptime;
ptime = gmtime(&now);
ptime->tm_year += 1900;
ptime->tm_mon += 1;
printf("global time is:\n%d-%d-%d %d: %d: %d\n", ptime->tm_year,
ptime->tm_mon, ptime->tm_mday, ptime->tm_hour, ptime->tm_min, ptime->tm_sec);

ptime = localtime(&now);
ptime->tm_year += 1900;
ptime->tm_mon += 1;
printf("local time is:\n%d-%d-%d %d: %d: %d\n", ptime->tm_year,
ptime->tm_mon, ptime->tm_mday, ptime->tm_hour, ptime->tm_min, ptime->tm_sec);

return 0;
}
结果:



时间相关的暂时只看了time、gmtime、localtime、struct tm、time_t;剩下的等用到了再回头看
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息