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

2024-08-22 04:38

本文主要是介绍APUE读书笔记-第六章 系统数据文件和信息,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

昨天看完了,今天来看看第六章。感觉第六章的内容不是非常重要。简单看看吧

 6.2 口令文件

口令文件其实就是/etc文件夹下的passwd文件,但处于安全性的考虑,我们无法直接读取它。就是通过直接限制权限的方式对其进行保护,passwd文件具体权限如下:

-rw-r--r-- 1 root root

可以看到只有root用户具有读写权限,与root同组的用户与其他用户仅具有读权限。

不过为了解决以上问题,Linux中给出了一系列数据结构与函数帮助我们操纵口令文件,首先是关键数据结构,定义位于/include/pwd.h

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.  */
};

给出用户登录名与数值用户ID后,通过以下两个函数就能获得passwd结构体,该结构体中包含有我们需要的信息。

#include <pwd.h>
extern struct passwd *getpwuid (__uid_t __uid);
extern struct passwd *getpwnam (const char *__name);

getpwuid函数由ls程序使用。getpwnam函数由login程序使用。passwd结构通常是函数内部的静态变量,只要调用任一相关函数,其内容就会被重写。

以上两个函数仅能查看某一个用户的口令信息,但如果不知道其他用户的登录名或数值ID,则无法获得这些信息。因此Linux中又给出了以下三个函数来查看整个口令文件。

#include <pwd.h>
extern struct passwd *getpwent (void); //若成功,返回指针,指向口令文件中的下一个记录项。第一次调用时,它打开所使用的各个文件。
extern void setpwent (void); //回到口令文件开头
extern void endpwent (void); //关闭口令文件

6.3节中所提到的阴影口令文件感觉与口令文件的内容并没有多大的差距,在此就先不深入研究了,以后遇到了再说。

6.4组文件

还是相同的思路,如果用户程序想访问组相关信息,这些信息虽然存放在/etc/group中,但还是由于权限的限制导致一般的用户无法直接访问这一问题。Linux中给出的方法是通过相关的函数与数据结构进行访问,首先来看关键数据结构。

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

通过组名与数值ID可以获得这一数据结构。

#include <grp.h>
extern struct group *getgrgid (__gid_t __gid);
extern struct group *getgrnam (const char *__name);

搜索整个口令文件则需要以下三个函数,思路也是一样的。

#include <grp.h>
extern void setgrent (void);
extern void endgrent (void);
extern struct group *getgrent (void);

6.5 附属组

引入附属组的一个原因是:一个用户会参与多个项目,因此也就要同时属于多个组。为了解决上述问题,4.2BSD引入了附属组的概念,用户不再简单的属于一个组,也可以属于多至16个另外的组。

用户程序可通过以下函数获取和设置附属组ID。

extern int getgrouplist (const char *__user, __gid_t __group,__gid_t *__groups, int *__ngroups);
extern int setgroups (size_t __n, const __gid_t *__groups) __THROW;
extern int initgroups (const char *__user, __gid_t __group);

其中setgroups需要超级用户权限调用,而由于initgroups需要调用setgroups,因此initgroups也同样只有超级用户才能调用。

6.7其他数据文件

除了上面提到的口令文件和组文件,Linux还有多个具有类似概念的文件。书中给出了一个表对上述内容进行总结。

说明数据文件头文件结构附加的减搜索函数
口令/etc/passwd<pwd.h>passwdgetpwnam/getpwuid
/etc/group<grp.h>groupgetgrnam/getgrgid
阴影口令/etc/shadow<shadow.h>spwdgetspnam
主机/etc/hosts<netdb.h>hostnetgetnameinfo/getaddrinfo
网络/etc/networks<netdb.h>netentgetnetbyname/getnetbyaddr
协议/etc/protocols<netdb.h>protonetgetprotobyname/getprotobynumber
服务/etc/services<netdb.h>serventgetserbyname/getserbyport

6.8登录账户记录

Linux通过“/var/run/utmp”对当前登录到系统的各个用户进行记录;通过“/var/log/wtmp”文件跟踪各个登录和注销事件。以上两个文件是二进制文件,不能直接打开。

Linux通过以下几个函数与数据结构对以上两个文件进行修改。首先来看看关键数据结构,定义位于/usr/include/x86_64-linux-gnu/bits/utmp.h中

struct utmp
{short int ut_type;		/* Type of login.  */pid_t ut_pid;			/* Process ID of login process.  */char ut_line[UT_LINESIZE];	/* Devicename.  */char ut_id[4];		/* Inittab ID.  */char ut_user[UT_NAMESIZE];	/* Username.  */char ut_host[UT_HOSTSIZE];	/* Hostname for remote login.  */struct exit_status ut_exit;	/* Exit status of a process markedas DEAD_PROCESS.  */
/* The ut_session and ut_tv fields must be the same size when compiled32- and 64-bit.  This allows data files and shared memory to beshared between 32- and 64-bit applications.  */
#ifdef __WORDSIZE_TIME64_COMPAT32int32_t ut_session;		/* Session ID, used for windowing.  */struct{int32_t tv_sec;		/* Seconds.  */int32_t tv_usec;		/* Microseconds.  */} ut_tv;			/* Time entry was made.  */
#elselong int ut_session;		/* Session ID, used for windowing.  */struct timeval ut_tv;		/* Time entry was made.  */
#endifint32_t ut_addr_v6[4];	/* Internet address of remote host.  */char __glibc_reserved[20];		/* Reserved for future use.  */
};

再来看看相关函数:

extern void login (const struct utmp *__entry) __THROW;

登录时,login程序填写此类型结构,然后将其写入到utmp文件中,同时也将其添写到wtmp文件中。通过login函数的参数也可以验证这一点。

注销时,init进程将utmp文件中相应的记录擦除,并将一个新记录添写到wtmp文件中。

6.9 系统标识

POSIX.1 定义了uname函数,它返回与主机和操作系统有关的信息。定义位于/usr/include/x86_64-linux-gnu/sys/utsname.h。

extern int uname (struct utsname *__name) __THROW; //__name即是输入参数也是输出参数。若程序运行成功返回非负值,若出错返回-1。

参数定义如下:

struct utsname{/* Name of the implementation of the operating system.  */char sysname[_UTSNAME_SYSNAME_LENGTH];/* Name of this node on the network.  */char nodename[_UTSNAME_NODENAME_LENGTH];/* Current release level of this implementation.  */char release[_UTSNAME_RELEASE_LENGTH];/* Current version level of this release.  */char version[_UTSNAME_VERSION_LENGTH];/* Name of the hardware type the system is running on.  */char machine[_UTSNAME_MACHINE_LENGTH];#if _UTSNAME_DOMAIN_LENGTH - 0/* Name of the domain of this node on the network.  */
# ifdef __USE_GNUchar domainname[_UTSNAME_DOMAIN_LENGTH];
# elsechar __domainname[_UTSNAME_DOMAIN_LENGTH];
# endif
#endif};

utsname结构体中的信息通常可用uname命令打印。我的机器上uname的返回结果非常简单

Linux

仅此而已,再无其他。

还有一个返回主机名的函数,该名字通常就是TCP/IP网络上主机的名字。

extern int gethostname (char *__name, size_t __len) __THROW __nonnull ((1));

其中name即是输入参数也是输出参数。

hostname命令可用来获取和设置主机名。主机名通常在系统自举时设置,它由/etc/rc或init取自一个启动文件。

6.10 时间和日期例程

由UNIX内核提供的基本时间服务是计算自协调世界时(Coordinated Universal Time,UTC)公元1970年1月1日00:00:00这一特定时间以来经过的秒数。这一秒数通过以下函数获得:

#include <time.h>
extern time_t time (time_t *__timer) __THROW;

通过clock_gettime同样可以获得这一秒数,但其时间精度更高:

#include <time.h>
extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) __THROW;

time与clock_gettime函数的结果可以直接相互转化。

time_t类型的参数可以通过gmtime函数转化为协调统一时间的年、月、日、时、分、秒、周日分解。这一格式的时间通过以下结构体表示。

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_MISClong int tm_gmtoff;		/* Seconds east of UTC.  */const char *tm_zone;		/* Timezone abbreviation.  */
# elselong int __tm_gmtoff;		/* Seconds east of UTC.  */const char *__tm_zone;	/* Timezone abbreviation.  */
# endif
};

这一类型需要通过strftime转化为字符串模式并输出。

extern size_t strftime (char *__restrict __s, size_t __maxsize,const char *__restrict __format,const struct tm *__restrict __tp) __THROW;

一个格式化的时间字符串可通过以下函数转化为结构体struct tm。

extern char *strptime (const char *__restrict __s,const char *__restrict __fmt, struct tm *__tp)__THROW;

struct tm结构体又可以通过mktime函数转化为time_t类型参数。

extern time_t mktime (struct tm *__tp) __THROW;

最后给大家附上各时间结构体之间的转化关系。



这篇关于APUE读书笔记-第六章 系统数据文件和信息的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1095267

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

软考系统规划与管理师考试证书含金量高吗?

2024年软考系统规划与管理师考试报名时间节点: 报名时间:2024年上半年软考将于3月中旬陆续开始报名 考试时间:上半年5月25日到28日,下半年11月9日到12日 分数线:所有科目成绩均须达到45分以上(包括45分)方可通过考试 成绩查询:可在“中国计算机技术职业资格网”上查询软考成绩 出成绩时间:预计在11月左右 证书领取时间:一般在考试成绩公布后3~4个月,各地领取时间有所不同

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti