一:口令文件的操作
/*****************************************
struct 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(用户程序)
/*************下列平台可能没有**************/
char* pw_class; //用户访问类
time_t pw_change; //下次更改口令时间
time_t pw_expire; //账户有效期时间
};
*****************************************/
/******************************************************
包含头文件: #include <pwd.h>
函数原型: struct passwd* getpwuid(uid_t uid);
函数说明: 通过用户ID获取口令文件项
返回值: 若成功,返回指针,若出错,返回NULL
*******************************************************/
/*******************************************************
包含头文件: #include <pwd.h>
函数原型: struct passwd* getpwuid(uid_t uid);
函数说明: 通过用户ID获取口令文件项
返回值: 若成功,返回NULL
********************************************************/
/**********************************************************
包含头文件: #include <pwd.h>
函数原型: struct passwd* getpwnam(const char* name);
函数说明: 通过用户名获取口令文件项
返回值: 若成功,若失败,返回NULL
**********************************************************/
/***********************************************************
包含头文件: #include <pwd.h>
函数原型: struct passwd* getpwent(void);
函数说明: 逐项遍历口令文件,返回当前口令文件项
返回值: 返回当前口令文件项,若到达文件尾,则返回NULL
***********************************************************/
/***********************************************************
包含头文件: #include <pwd.h>
函数原型: void setpwent(void);
函数说明:回绕到口令文件首项
**********************************************************/
/**********************************************************
包含头文件: #include <pwd.h>
函数原型: void endpwent(void);
函数说明: 关闭口令文件
*************************************************************/
vi 6.1.c
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(int argc,char* argv[])
{
if (argc != 2)
{
printf("add <pathname>\n");
exit(0);
}
struct stat statbuf;
if (lstat(argv[1],&statbuf) < 0)
{
printf("lstat error\n");
exit(0);
}
struct passwd* pw;
if ((pw = getpwuid(statbuf.st_uid)) == NULL)
{
printf("getpwuid error\n");
exit(0);
}
printf("用户名: %s\n",pw->pw_name);
printf("加密口令: %s\n",pw->pw_passwd);
printf("用户ID: %d\n",pw->pw_uid);
printf("组ID: %d\n",pw->pw_gid);
printf("初始工作目录: %s\n",pw->pw_dir);
printf("初始shell: %s\n",pw->pw_shell);
return 0;
}
vi 6.1.1.c
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
struct passwd* pw;
if ((pw = getpwnam("root")) == NULL)
{
printf("getpwnam error\n");
exit(0);
}
printf("用户名: %s\n",pw->pw_gid);
printf("注释字段: %s\n",pw->pw_gecos);
printf("初始工作目录: %s\n",pw->pw_shell);
exit(0);
}
vi 6.2.c
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
setpwent();
struct passwd *pw;
while ((pw = getpwent()) != NULL)
{
printf("用户名: %s\n",pw->pw_passwd);
printf("用户ID:%d\n",pw->pw_dir);
printf("初始shell: %s\n\n",pw->pw_shell);
}
endpwent();
}
二. 阴影口令文件
阴影口令文件项结构体
/***********************************************************
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; //保留
}
*********************************************************/
/***********************************************************
包含头文件: #include <shadow.h>
函数原型: struct spwd* getspname(const char* name);
函数说明: 得到阴影口令文件项
返回值: 若成功,返回指针,返回NULL
**********************************************************/
vi 6.3.c
#include <shadow.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
struct spwd* spw;
if ((spw = getspnam("root")) == NULL)
{
printf("getspnam error\n");
exit(0);
}
printf("用户名: %s\n",spw->sp_namp);
printf("加密口令: %s\n",spw->sp_pwdp);
printf("上次口令更改以来经过的时间: %ld\n",spw->sp_lstchg);
printf("经过多少天后允许更改: %ld\n",spw->sp_min);
printf("要求更改尚余天数: %ld\n",spw->sp_warn);
printf("账户不活动前尚余天数: %ld\n",spw->sp_inact);
printf("账户超期天数: %ld\n",spw->sp_expire);
exit(0);
}
/***********************************************************
包含头文件: #include <shadow.h>
函数原型: void setspent();
函数说明: 回绕到文件开头项
*******************************************************/
/*******************************************************
包含头文件: #include <shadow.h>
函数原型: struct spwd* getspent();
函数说明: 打开阴影口令文件,并返回当前阴影口令文件项
*******************************************************/
/********************************************************
包含头文件: #include <shadow.h>
函数原型: void endspent();
函数说明: 关闭阴影口令文件
********************************************************/
vi 6.4.c
#include <shadow.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
struct spwd* spw;
setspent();
while ((spw = getspent()) != NULL)
{
printf("用户名: %s\n",spw->sp_pwdp);
printf("上次更改口令以来经过的时间: %ld\n",spw->sp_lstchg);
printf("经过多少天允许更改: %ld\n",spw->sp_max);
printf("超期警告天数: %ld\n",spw->sp_warn);
printf("账户不活动之前尚余天数: %ld\n",spw->sp_expire);
}
return 0;
}
三: 组文件
/**********************************************************
组文件结构体:
struct group
{
char* gr_name; //组名
char* gr_passwd; //加密口令
int gr_gid; //数值组ID
char **gr_mem; //指向各用户名指针的数组
}
***********************************************************/
/*******************************************************
包含头文件: #include <grp.h>
函数原型: struct group* getgrgid(gid_t gid);
函数说明: 通过组ID获得组文件组项
返回值: 若成功,返回组文件组项指针,返回NULL
********************************************************/
vi 6.5.c
#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
struct group* gr;
if ((gr = getgrgid(0)) == NULL)
{
printf("getgrgid error\n");
exit(0);
}
printf("组名: %s\n",gr->gr_name);
printf("加密口令: %s\n",gr->gr_passwd);
printf("组ID: %d\n",gr->gr_gid);
printf("该组成员:\n");
int i = 0;
while ((gr->gr_mem)[i] != NULL)
{
printf("组内用户: %s\n",(gr->gr_mem[i]));
++i;
}
return 0;
}
/***********************************************************
包含头文件: #include <grp.h>
函数原型: struct group* getgrnam(const char* name);
函数说明: 通过组ID获得组文件组项指针,返回
NULL
**********************************************************/
#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
setgrent();
struct group* gr;
while ((gr = getgrent()) != NULL)
{
printf("组名: %s\n",gr->gr_passwd);
printf("组ID: %d\n",gr->gr_gid);
int i = 0;
while ((gr->gr_mem)[i] != NULL)
{
printf("组内用户名: %s\n",(gr->gr_mem[i]));
++i;
}
}
return 0;
}
/*********************************************************
包含头文件: #include <unistd.h>
函数原型:int getgroups(int gidsetsize,gid_t grouplist[]);
函数说明: getgroups将进程所属用户的各附属组ID,填写到数组grouplist中,填写入该数组附属组ID最多为gidsize个,实际填写附属组ID数由函数返回
作为一种特殊情况,如若gidsize为0,则函数返回附属组ID数,而对数组grouplist不做修改
返回值: 若成功,返回附属组ID数量,若出错,返回-1
*********************************************************/
vi 6.9.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
gid_t * grouplist;
int size;
if ((size = getgroups(0,grouplist)) == -1)
{
printf("getgroups error\n");
exit(0);
}
grouplist = (gid_t*)(malloc(size * sizeof(gid_t)));
int get;
if ((get = getgroups(size,grouplist)) == -1)
{
printf("getgroups error\n");
exit(0);
}
for (int i = 0; i < get; ++i)
printf("附属组号: %d\n",grouplist[i]);
return 0;
}
/***********************************************************
包含头文件: #include <grp.h> //on linux
#include <unistd.h> // on FreeBSD,Mac Os X,
and Solaris
函数原型: int setgroups(int ngroups,const gid_t
grouplist[]);
函数说明:由超级用户调用以便为调用进程设置附属组ID表
返回值: 若成功,返回0,若出错,返回-1
*******************************************************/
/*********************************************************
包含头文件:#include <grp.h> // on linux and Solaris
#include <unistd.h> // on FreeBSD and Mac Os X
函数原型: int initgroups(const char* username,gid_t basegid);
函数说明: 为用户初始化附属组ID表
返回值: 若成功,返回0,若失败,返回-1
****************************************************/
/**********************************************************
struct utsname
{
char sysname[]; //操作系统名称
char nodename[]; //网络上的名称
char release[]; //当前发布级别
char version[]; //当前发布版本
char machine[]; //当前硬件体系类型
}
**********************************************************/
/***********************************************************
包含头文件: #include <sys/utsname.h>
函数原型: int uname(struct utsname* name);
函数说明: 得到主机和操作系统有关信息
返回值: 若成功,返回非负值,返回-1
**********************************************************/
vi 6.9.1.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/utsname.h>
int main()
{
struct utsname name;
if (uname(&name) < 0)
{
printf("uname error\n");
exit(0);
}
printf("操作系统名称: %s\n",name.sysname);
printf("网络名称: %s\n",name.nodename);
printf("当前发布级别: %s\n",name.release);
printf("当前发布版本: %s\n",name.version);
printf("当前硬件体系类型: %s\n",name.machine);
exit(0);
}
vi 6.9.2.c
/***********************************************************
包含头文件: #include <unistd.h>
函数原型: int gethostname(char* name,int namelen);
函数说明: 得到主机名,该主机名通常为TCP/IP网络主机的名字
返回值: 若成功,返回0,若失败,返回-1
**********************************************************/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define HOST_NAME_MAX 300
int main()
{
char hostname[HOST_NAME_MAX];
if (gethostname(hostname,HOST_NAME_MAX) < 0)
{
printf("gethostname error\n");
exit(0);
}
printf("主机名: %s\n",hostname);
exit(0);
}
四: 时间和例程
/*************************************************************
包含头文件: #include <time.h>
函数原型: time_t time(time_t *calptr);
函数说明: 返回当前时间和日期
时间值作为函数值返回,如果参数非空,则时间值也存放
在由calptr指向的单元内
返回值: 若成功,返回时间值,若出错,返回-1
*************************************************************/
vi 6.10.c
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#define SIZE 100
int main()
{
time_t t = time(NULL);
char str[SIZE];
strftime(str,SIZE,"%Y %x %X\n",localtime(&t));
printf("当前时间: %s\n",str);
return 0;
}
/*************************************************************
时钟通过clockid_t类型标识:
标识符 选项 说明
CLOCK_REALTIME 实时系统时间
CLOCK_MONTONIC _ POSIX_MONOTONIC_CLOCK 不带负跳数的实时系统时间
CLOCK_PROCESS_cpuTIME_ID POSIXcpuTIME 调用进程的cpu时间
CLOCK_THREAD_cpuTIME_ID POSIXTHREAD_cpuTIME 调用线程的cpu时间
***********************************************************/
/*********************************************************
包含头文件: #include <sys/time.h>
函数原型: int colck_gettime(clockid_t clock_id,struct timespec *tsp);
函数说明: 获取指定时钟的时间
返回值: 若成功,返回-1
*********************************************************/
vi 6.10.1.c
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
char* get_time(clockid_t clockid,char* s)
{
struct timespec ts;
if (clock_gettime(clockid,&ts) == -1)
{
printf("clock_gettime error\n");
exit(0);
}
time_t t = ts.tv_sec;
char str[100];
if (strftime(str,100,"%Y %x %X",localtime(&t)) == 0)
{
printf("strftime error\n");
exit(0);
}
s = str;
return s;
}
int main()
{
char* s;
printf("实时系统时间: %s\n",get_time(CLOCK_REALTIME,s));
printf("不带负跳数的实时系统时间: %s\n",get_time(CLOCK_MONOTONIC,s));
printf("调用进程的cpu时间: %s\n",get_time(CLOCK_PROCESS_cpuTIME_ID,s));
printf("调用线程的cpu时间: %s\n",get_time(CLOCK_THREAD_cpuTIME_ID,s));
return 0;
}
/*********************************************************
包含头文件: #include <sys/time.h>
函数原型: int clock_getres(clockid_t clock_id,struct timespec *tsp);
函数说明:把参数tsp指向的timespec结构初始化为与
clock_id参数对应的时钟精度
***********************************************************/
/***********************************************************
包含头文件: #include <sys/time.h>
函数原型:int clock_settime(clockid_t clock_id,const
struct timespec *tsp);
函数说明:对特定的时钟设置时间
返回值:若成功,返回0,若出错,返回-1
***********************************************************/
/**********************************************************
包含头文件: #include <sys/time.h>
函数原型: int gettimeofday(struct timeval* restrict tp,void * restrict tzp);
函数说明: tzp唯一合法值是NULL,其他值将产生不确定的结果(某些平台支持用tzp说明时区)
gettimeofday函数以距特定时间的秒数的方式将时间存放于tp指向的timeval结构
**********************************************************/
vi 6.10.2
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define BUFSIZE 100
int main()
{
char buf[BUFSIZE];
struct timespec* curr_ts = (struct timespec*)(malloc(sizeof(struct timespec)));
if (clock_gettime(CLOCK_REALTIME,curr_ts) < 0)
{
printf("clock_gettime error\n");
free(curr_ts);
exit(0);
}
time_t curr = curr_ts->tv_sec;
strftime(buf,BUFSIZE,"%Y %x %X",localtime(&curr));
printf("未修改时的实时系统时间: %s\n",buf);
struct timespec *ts = (struct timespec*)(malloc(sizeof(struct timespec)));
ts->tv_sec = curr + 60 * 3;
ts->tv_nsec = curr_ts->tv_nsec;
if (clock_settime(CLOCK_REALTIME,ts) < 0)
{
printf("clock_settime error\n");
free(curr_ts);
free(ts);
exit(0);
}
time_t now = time(NULL);
strftime(buf,"%Y %x %X\n",localtime(&now));
printf("增加三分钟的实时系统时间: %s\n",buf);
free(curr_ts);
free(ts);
return 0;
}
/**********************************************************
结构体 struct tm
{
int tm_sec; //秒
int tm_min; //分
int tm_hour; //时
int tm_mday; //日 of 月
int tm_mon; //月
int tm_year; //年
int tm_wday; //日 of 周
int tm_yady; //日 of 年
int tm_isdst; //夏令时标识符 若为正,开启标识符,
若为0,关闭夏令时,若为负,未知
}
********************************************************/
/**********************************************************
包含头文件: #include <time.h>
函数原型: struct tm* localtime(const time_t *calptr);
函数说明: 将日历时间转换为本地时间
返回值: 若成功,返回结构体tm指针,若出错,返回NULL
**********************************************************/
/**********************************************************
包含头文件: #include <time.h>
函数原型: struct tm* gmtime(const time_t* calptr);
函数说明:将日历时间转化为协调统一时间
返回值: 若成功,返回结构体tm指针,返回NULL
***********************************************************/
/*************************************************************
包含头文件: #include <time.h>
函数原型: time_t mktime(struct tm* tmptr);
函数说明: 将tm结构体指针分解成time_t并返回
返回值: 若成功,返回日历时间,若失败,返回-1
************************************************************/
vi 6.11.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define BUFSIZE 100
int main()
{
char buf[BUFSIZE];
struct tm mytm;
mytm.tm_sec = 00;
mytm.tm_min = 59;
mytm.tm_hour = 11;
mytm.tm_mday =01;
mytm.tm_mon = 04;
mytm.tm_year = 98;
mytm.tm_isdst = -1;
strftime(buf,&mytm);
printf("我的TM: %s\n",buf);
return 0;
}