《APUE》chapter 6 System Data files and information 学习笔记(加上自己的代码)

System Data files and information

Password  File

            POSIX.1  defines  two  functions  to fetch  entries  from  the  password file. These functions allow us to look up an entry given a user’s loginname or numerical user ID.

 

#include <pwd.h>
struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *name);
Both return: pointer if OK, NULL on error




在pwd.h里面定义了passwd结构体

/* The passwd structure. */
struct passwd
{
  char *pw_name;                /* Username.  */
  char*pw_passwd;              /*Password.  */
  __uid_t pw_uid;               /* User ID.  */
  __gid_t pw_gid;               /* Group ID.  */
  char *pw_gecos;               /* Real name.  */
  char *pw_dir;                 /* Home directory.  */
  char *pw_shell;               /* Shell program.  */
};
 


linux 的passwd结构体有些变量和UNix有点不一样,少了

user access class    char *pw_class 

next time to change password    time_tpw_change 

account expiration time     time_tpw_expire

 

#include <pwd.h>
#include <stdio.h>
 
int main()
{
        struct passwd*p_passwd =  NULL;
 
        p_passwd =getpwnam("liuzjian");
 
       printf("the user name:%s\n",p_passwd->pw_name);
       printf("the numberical user ID:%u\n",p_passwd->pw_uid);
       printf("the numberical group ID:%u\n",p_passwd->pw_gid);
       printf("the comment field:%s\n",p_passwd->pw_gecos);
       printf("the initial workingdirectory:%s\n",p_passwd->pw_dir);
       printf("the initial shell:%s\n",p_passwd->pw_shell);
/*     printf("the user access class:%s\n",p_passwd->pw_class);
       printf("the next time to changepassword:%d\n",p_passwd->pw_change);
       printf("the account expirationtime:%d\n",p_passwd->pw_expire);
*/      return 0;
}


test result:
root@ubuntu:/Ad_Pro_in_Unix/chapter_6# ./a.out
the user name:liuzjian
the numberical user ID:1000
the numberical group ID:1000
the comment field:liuzjian,,,
the initial working directory:/home/liuzjian
the initial shell:/bin/bash

 

#include <pwd.h>
struct passwd *getpwent(void);
Returns: pointer if OK,NULL on error or end of file
void setpwent(void);
void endpwent(void);



getpwent()是获得执行该程序的用户的passwd 结构体

#include <pwd.h>
#include <stdio.h>
 
int main()
{
        struct passwd*p_passwd =  NULL;
 
        setpwent();
        p_passwd =getpwent();
 
        printf("theuser name:%s\n",p_passwd->pw_name);
       printf("the numberical user ID:%u\n",p_passwd->pw_uid);
       printf("the numberical group ID:%u\n",p_passwd->pw_gid);
       printf("the comment field:%s\n",p_passwd->pw_gecos);
       printf("the initial workingdirectory:%s\n",p_passwd->pw_dir);
       printf("the initial shell:%s\n",p_passwd->pw_shell);
 
        endpwent();
        return 0;
}


 

The function setpwent re winds whatever files it uses, and endpwent closes these files.  When using getpwent , we must always  be  sure to close  these  files  by calling endpwent when we’re through.  Although getpwent is smart enough to know when it has to open its files (the first time we call it), it never knows when we’re through.

 

test result:

root@ubuntu:/Ad_Pro_in_Unix/chapter_6# ./b.out
the user name:root
the numberical user ID:0
the numberical group ID:0
the comment field:root
the initial working directory:/root
the initial shell:/bin/bash

 

 

APUE 给出的getpwnam的一个实现:

/************************************************************
just a implementation of getpwname function
*************************************************************/
#include "pwd.h"
#include "stdef.h"
#include "string.h"
 
struct passwd*
getpwname(const char*name)
{
        struct passwd*ptr = NULL;
        setpwent();
 
        while((ptr =getpwent()) != NULL)
        {
               if((strcmp(name,ptr->pw_name)) == 0)
                {
                       break;
                }    
        }
                endpwent();
 return ptr;
}


 

Shadow Passwords

 

linux下spwd的结构体定义

/* Structure of the password file.  */
struct spwd
  {
    char*sp_namp;              /* Loginname.  */
    char*sp_pwdp;              /* Encryptedpassword.  */
    long intsp_lstchg;         /* Date of lastchange.  */
    long intsp_min;            /* Minimum number ofdays between changes.  */
    long intsp_max;            /* Maximum number ofdays between changes.  */
    long intsp_warn;           /* Number of days towarn user to change
                                   thepassword.  */
    long intsp_inact;          /* Number of days theaccount may be
                                  inactive.  */
    long intsp_expire;         /* Number of days since1970-01-01 until
                                   accountexpires.  */
    unsigned long intsp_flag;  /* Reserved.  */
  };


 

#include <shadow.h>
struct spwd *getspnam(const char *name);
struct spwd *getspent(void);
Both return: pointer if OK, NULL on error

void setspent(void);
void endspent(void);
 
test code:
#include <stdio.h>
#include <shadow.h>
 
int main()
{
        struct spwd*p_spwd = NULL;
 
        if((p_spwd =getspnam("liuzjian")) == NULL)
        {
                printf("getspnam error\n");
        }
 
       printf("user login name :%s\n",p_spwd->sp_namp);
       printf("encrypted password: %s\n",p_spwd->sp_pwdp);
       printf("day since Epoch of last password change:%ld\n",p_spwd->sp_lstchg);
        printf("days until change allowed:%ld\n",p_spwd->sp_min);
       printf("days before change required:%ld\n",p_spwd->sp_max);
       printf("days warning forexpiration:%ld\n",p_spwd->sp_warn);
       printf("days before account inactive:%ld\n",p_spwd->sp_inact);
       printf("days since Epoch when accountexpires:%ld\n",p_spwd->sp_expire);
       printf("reserved :%lu\n",p_spwd->sp_flag);
 
        return 0;
}


test result:

root@ubuntu:/Ad_Pro_in_Unix/chapter_6# ./a.out
user login name :jasonleaster
encrypted password: $1$EI.fFLyC$3ogyqNY162jmeWntAMdVE1
day since Epoch of last password change :15896
days until change allowed :0
days before change required:99999
days warning for expiration:7
days before account inactive:-1
days since Epoch when account expires:-1
reserved :18446744073709551615

 

 

 

Group  File

linux 下grp.h 中 group结构体的定义

/* The group structure. */
struct group
  {
    char*gr_name;              /* Groupname.  */
    char*gr_passwd;            /* Password.    */
    __gid_t gr_gid;             /* Group ID.    */
    char**gr_mem;              /* Member list. */
  };


 

These fields are contained in a group structure that isdefined in <grp.h>.

#include <grp.h>
struct group *getgrgid(gid_t gid);
struct group *getgrnam(const char *name);
Both return: pointer if OK, NULL on error
 
#include <grp.h>
struct group *getgrent(void);
Returns: pointer if OK,NULL on error or end of file
void setgrent(void);
void endgrent(void);


       The setgrent function opens the group file, if it’s not already open, and rewinds it.  The getgrent function  reads  the next entry  from  the  group  file,  opening the  file first, if it’s not already open. The endgrent function closes the group file.

 

#include <stdio.h>
#include <grp.h>
 
int main()
{
        struct group*p_group = NULL;
 
        if((p_group =getgrnam("liuzjian")) == NULL)
        {
               printf("getgrnam error\n");
        }
 
       printf("group name :%s\n",p_group->gr_name);
       printf("encrypted passwd:%s\n",p_group->gr_passwd);
       printf("numberical group ID:%d\n",p_group->gr_gid);
       printf("array of pointers of individual user names:%s\n",*(p_group->gr_mem));
 
        return 0;
}


test result:

root@ubuntu:/Ad_Pro_in_Unix/chapter_6# ./a.out 
group name :jasonleaster
encrypted passwd:x
numberical group ID:1000
array of pointers of individual user names :(null)

 

The field gr_mem is an array of pointers to the user names that belong to this group. This array is terminated by a null pointer

 

Other Data  Files

 

The general principle is that every data file has at leastthree functions:

1.A get function  that  reads  the  next record,  opening  the  file  if  necessary .

2.A set function that opens the file, if not already open,and rewinds the file.

3.An end entry that closes the data file. 

 

 

 

System Identification

 

linux下面ustname 结构体的定义

/* Structure describing the system and machine.  */
struct utsname
  {
    /* Name of theimplementation of the operating system. */
    charsysname[_UTSNAME_SYSNAME_LENGTH];
 
 
    /* Name of thisnode on the network.  */
    charnodename[_UTSNAME_NODENAME_LENGTH];
 
 
    /* Current releaselevel of this implementation.  */
    charrelease[_UTSNAME_RELEASE_LENGTH];
    /* Current versionlevel of this release.  */
    charversion[_UTSNAME_VERSION_LENGTH];
 
 
    /* Name of thehardware type the system is running on. */
    charmachine[_UTSNAME_MACHINE_LENGTH];
 
 
#if _UTSNAME_DOMAIN_LENGTH - 0
    /* Name of thedomain of this node on the network.  */
# ifdef __USE_GNU
    chardomainname[_UTSNAME_DOMAIN_LENGTH];
# else
    char__domainname[_UTSNAME_DOMAIN_LENGTH];
# endif
#endif
  };


 

Each string is null terminated. The maximum name lengths,including the terminating null byte.

 

/***************************************************************************
code writer :EOF
code date : 2014.03.25
e-mail : jasonleaster@gmail.com
code purpose:
        just a demofor uname function. I would like to share my code with
you. If you find something thing wrong with my code, pleasetouche me
by e-mail. Thank you!
 
****************************************************************************/
#include <stdio.h>
#include <sys/utsname.h>
#include <stdlib.h>
 
int main()
{
        structutsname* p_utsname = NULL;
       
        if((p_utsname= (struct utsname*)malloc(sizeof(struct utsname))) == NULL)
        {
               printf("malloc error\nprocess end\n");
                return0;
        }      
 
       if((uname(p_utsname)) < 0)
        {
               printf("uname error\n");
        }
        else
        {
               printf("name of the operatingsystem:%s\n",p_utsname->sysname);
                printf("name of thisnode:%s\n",p_utsname->nodename);
               printf("current release of operatingsystem:%s\n",p_utsname->release);
               printf("current version of thisrelease:%s\n",p_utsname->version);
               printf("name of hard ware type:%s\n",p_utsname->machine);
        }
       
       free(p_utsname);
        return 0;
}


test result:
root@ubuntu:/Ad_Pro_in_Unix/chapter_6# ./a.out
name of the operating system:Linux
name of this node:ubuntu
current release of operating system:3.8.0-19-generic
current version of this release:#29-Ubuntu SMP Wed Apr 17 18:16:28 UTC 2013
name of hard ware type:x86_64


hostname function:

 

#include <unistd.h>
int gethostname(char *name,int namelen);
Returns: 0 if OK,−1 on error
 
test code:
/***************************************************************************
code writer :EOF
code date : 2014.03.25
e-mail : jasonleaster@gmail.com
code purpose:
        just a demofor gethostname function. I would like to share my code with
you. If you find something thing wrong with my code, pleasetouche me
by e-mail. Thank you!
 
****************************************************************************/
#include <unistd.h>
#include <stdio.h>
 
int main()
{
        charbuffer[BUFSIZ];
 
        if(gethostname(buffer,BUFSIZ) != 0)
        {
               printf("gethostname error\n");
        }
        else
        {
               printf("host name:%s\n",buffer);
        }
 
        return 0;
}


test result:

root@ubuntu:/Ad_Pro_in_Unix/chapter_6# ./a.out
host name:ubuntu

Time and  Date  Routines

 

/* Used by other time functions.  */
struct tm
{
  int tm_sec;                   /* Seconds.     [0-60] (1 leap second) */
  int tm_min;                   /* Minutes.     [0-59] */
  int tm_hour;                  /* Hours.       [0-23] */
  int tm_mday;                  /* Day.         [1-31] */
  int tm_mon;                   /* Month.       [0-11] */
  int tm_year;                  /* Year - 1900.  */
  int tm_wday;                  /* Day of week. [0-6] */
  int tm_yday;                  /* Days in year.[0-365] */
  int tm_isdst;                 /* DST.         [-1/0/1]*/
 
# ifdef __USE_BSD
  long inttm_gmtoff;           /* Seconds east ofUTC.  */
  const char *tm_zone;          /* Timezone abbreviation.  */
# else
  long int__tm_gmtoff;         /* Seconds east ofUTC.  */
  const char*__tm_zone;        /* Timezoneabbreviation.  */
# endif
};


 

#define             __TIME_T_TYPE           __SYSCALL_SLONG_TYPE

 

__STD_TYPE  __TIME_T_TYPE        __time_t;      /* Seconds since the Epoch.  */

 

__STD_TYPE  __SYSCALL_SLONG_TYPE   __syscall_slong_t;

 

在linux里面找了几个文件,发现上面这些“蛛丝马迹”,找到syscall_slong_t就找不到下文了。。。但是可以很明显的看出time_t是个长整型数据。。。

(

update : 2014.08.09

time_t 应该不是long 而是signed int!

今天回过头看的时候,找了time_t的定义

看到time_t 一开始是__ketnel_time_t

然后__kernel_time_t是 __kernel_long_t

__kernel_long_t是__kernel_ssize_t

__kernel_ssize_t是int!!!


linux 内核版本3.13.0

#include <stdio.h>
#include <time.h>
 
int main()
{
        time_tbuffer[BUFSIZ];
 
       printf("%ld\n",time(buffer));
 
        return 0;
}


root@ubuntu:/Ad_Pro_in_Unix/chapter_6# ./a.out
1395738306
 

我始终没明白,这串数字神马意思,有大神路过帮忙解释一下。。。

 

update:2014.04.02   00:34

貌似还是自己解决比较靠谱。。。

上面那个数字是以秒为单位是时间系统时间,具体是神马时间我就布吉岛。。。


update:2014.04.28 10:54

上面那个时间还是自己搞明白了。。。是以秒为单位的时间,从1970年1月1日0时0分0秒到现在的。。。

((((1395738306-1395738306%(365*24*3600))/365)/24)/3600) = 44 你懂的1970+44 嗯哼

测试demo:

 

#include <stdio.h>
#include <time.h>
int main()
{
        time_t t;
        int temp = 0;
 
 
        t =time(NULL);
 
 
        for(temp =0;temp < 3;)
        {
               if(time(NULL) - t > 1)
                {
                       printf("hello world!\n");
                       temp++;
                       t = time(NULL);
                }
        }
        return 0;
}


这个demo会每各一秒打印一个helloworld!

 

 

#include <sys/time.h>
int clock_gettime(clockid_t clock_id,struct timespec *tsp);
Returns: 0 if OK,−1 on error
 
#include <sys/time.h>
int clock_getres(clockid_t clock_id,struct timespec *tsp);
Returns: 0 if OK,−1 on error
 
#include <sys/time.h>
int clock_settime(clockid_t clock_id,const struct timespec*tsp);
Returns: 0 if OK,−1 on error
 
#include <sys/time.h>
int gettimeofday(struct timeval *restrict tp ,void *restricttzp);
Returns: 0 always
 
#include <time.h>
struct tm *gmtime(const time_t *calptr);
struct tm *localtime(const time_t *calptr);
Both return: pointer to broken-down time, NULL on error
 
#include <time.h>
time_t mktime(struct tm *tmptr);
Returns: calendar time if OK, −1 on error
 
#include <time.h>
size_t strftime(char *restrictbuf,size_tmaxsize,
const char *restrict format ,
const struct tm *restrict tmptr);
size_t strftime_l(char *restrict buf,size_tmaxsize,
const char *restrict format ,
const struct tm *restrict tmptr,locale_t locale);
Both return: number of characters stored in array if room, 0otherwise


 


strtime 函数参数列表中变量format的选项。。。下表

 






#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
        time_t buffer[BUFSIZ];
        struct tm* p_tm = NULL;

        time(buffer);

        if((p_tm = (struct tm*)malloc(sizeof(struct tm))) == NULL)
        {
                printf("malloc error\nprocess end\n");
                return 0;
        }

        mktime(p_tm);

        printf("%s\n",asctime(p_tm));

        printf("%s\n",ctime(buffer));

        free(p_tm);
        return 0;
}




root@ubuntu:/Ad_Pro_in_Unix/chapter_6# ./a.out
Sun Dec 31 00:00:00 1899


Tue Mar 25 17:55:44 2014

我始终觉得这个输出有问题,但是布吉岛为什吗。。。是1899年。。。非常欢迎feedback。。。












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值