apue第六章学习总结
1.关于阴影文件与口令
在口令文件当中,常见的字段有(以root为例):
root(用户名):x(加密口令):0(uid):0(gid):root(注释字段):/root(用户所在根目录):/bin/bash(用户的shell所在目录)
注意:这里的加密口令只是一个占位符号,真正的加密口令存于阴影文件当中,阴影口令文件不应是一般用户可以读取的。仅有少数几个程序需要存取加密口令,例如login(1)
和passwd(1)
,这些程序常常是设置用户ID为root的程序。用了阴影口令后,普通文件/etc/passwd
可由各用户自由读取。
在linux下,以下代码会输出加密口令(从阴影口令文件中拉取):
#include "apue.h"
#include <shadow.h>
int main(){
struct spwd *ptr;
if((ptr = getspnam("sysublackbear")) == NULL){
err_sys("getspnam error");
}
printf("sp_pwdp = %s\n", ptr->sp_pwdp == NULL || ptr->sp_pwdp[0] == 0 ? "(null)":ptr->sp_pwdp);
return 0;
}
2.编写一个程序,它调用uname
并输出utsname
结构中的所有字段,将该输出与uname -a
命令的输出结果作比较。
本题难度并不大,注意记得函数赋值给一个指向结构体的指针时记得向内存分配一块空间,否则调用uname()
函数时会失败。
代码如下:
#include "apue.h"
#include <sys/utsname.h>
int main() {
struct utsname* ptr;
//在调用函数uname时先开辟一块新的空间,如果将指针设为NULL,下面函数不会运行成功,因为系统没有为其开辟内存空间
ptr = (struct utsname*)malloc(sizeof(struct utsname));
int temp;
if(temp = uname(ptr) == -1){
err_sys("uname error");
}
//写成uname -a 的形式
printf("%s %s %s %s %s\n",ptr->sysname == NULL ? "(NULL)" : ptr->sysname,
ptr->nodename == NULL ? "(NULL)" : ptr->nodename,
ptr->release == NULL ? "(NULL)" : ptr->release,
ptr->version == NULL ? "(NULL)" : ptr->version,
ptr->machine == NULL ? "(NULL)" : ptr->machine
);
return 0;
}
3.编写一个程序,获取当前时间,并使用strftime
将输出结果转换为类似于date
命令的默认输出。将环境变量TZ设置为不同的值,观察输出结果。
代码如下:
#include "apue.h"
#include <time.h>
int main() {
time_t caltime;
struct tm *tm;
char line[MAXLINE];
//获取当前时间
if((caltime = time(NULL)) == -1){
err_sys("time error");
}
//将当前时间转换为对应的日历时间,存到tm结构体中
if((tm = localtime(&caltime)) == NULL){
err_sys("localtime error");
}
//再将日历时间打印成date的格式
if(strftime(line,MAXLINE,"%a %b %d %X %Z %Y\n",tm) == 0){
err_sys("strftime error");
}
//打印字符串(将字符数组输出到stdout流当中)
fputs(line,stdout);
return 0;
}