UNIX系统文件

密码文件

密码文件又称用户数据库,一般为/etc/passwd,对应的结构为struct passwd,该文件内容大体如下:

描述 passwd字段
用户名 char* pw_name
加密密码 char* pw_passwd
UID uid_t  pw_uid
GID gid_t  pw_gid
注释 char* pw_gecos
初始工作目录 char* pw_dir
shell char* pw_shell

加密密码一般一个字符,如果没有值说明该用户没有密码,这个字符只是表象,不是真正的加密密码,加密密码在/etc/shadow中

shell值为shell解释器程序的绝对路径,shell为/bin/false /bin/true /dev/null 都是禁止登录的

用户名为nobody的用户,系统允许向系统写日志,只能访问那些能被其他访问的文件

通过下面函数可以获取对应的struct passwd结构:

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

这两个函数返回值都是静态存储的,所以在此调用内容会被覆盖,在多线程环境下应该使用可重入的替代函数:

int getpwnam_r(const char *name, struct passwd *pwd,char *buf, size_t buflen, struct passwd **result);

 int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result);

成功返回0,*result值pwd,失败返回0,*result 为NULL

如果想遍历所有结构,使用下面的函数:

#include <pwd.h>
struct passwd *getpwent(void);//返回一条密码数据库记录
//Returns: pointer if OK, NULL on error or end of ?le
void setpwent(void);//返回到密码数据的开始
void endpwent(void);//关闭密码数据库

下面遍历数据库,查找对应的结构:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <pwd.h>

int serchsth(const char* name)
{
    struct passwd *ptr;
    int ret = -1;
    setpwent();

    while((ptr = getpwent())!= NULL )
    {

        if(strcmp(name,ptr->pw_name) == 0 )
        {
            printf("we got something:%s\n",ptr->pw_name);
            ret = 0;
            break;
        }
    }
    endpwent();
    return ret;
}

int main(int argc,char* argv[])
{
    return serchsth("hero");
}

加密密码存在/etc/shadow中,加密算法是单向加密,所以很通过加密密码难猜测出原始密码,对应的有函数获取对应的加密记录以及遍历所有记录:

#include <shadow.h>
struct spwd *getspnam(const char *name);
struct spwd *getspent(void);
//Both return: pointer if OK, NULL on error
//下面是上面两个可重入对应函数
 int getspent_r(struct spwd *spbuf, char *buf, size_t buflen, struct spwd **spbufp);
 int getspnam_r(const char *name, struct spwd *spbuf,char *buf, size_t buflen, struct spwd **spbufp);

void setspent(void);
void endspent(void);

同样地有相似获取组信息的函数

#include <grp.h>
struct group *getgrent(void);
//Returns: pointer if OK, NULL on error or end of ?le
void setgrent(void);
void endgrent(void);

一个用户拥有一个组之外还可以属于多个组,这些组称为附加组,通过下面函数可以获取和设置附加组:

#include <sys/types.h>
 #include <unistd.h>

 int getgroups(int size, gid_t list[]);

 #include <grp.h>

 int setgroups(size_t size, const gid_t *list);

#include <sys/types.h>
#include <grp.h>

 int initgroups(const char *user, gid_t group);

//return 0 sucess -1 failed

getgroups 获取size指定个数的附加组,值存在list中,当size为0的时候,返回附加组个数。这可以用来确定要开辟多大的数组。

setgroups设置附加组,initgroups获取用户对应的组信息,只有特权才能操作这两个函数。

系统信息

获取当前主机和操作系统信息:

#include <sys/utsname.h>

       int uname(struct utsname *buf);
      // On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

获取主机名:

#include <unistd.h>
int gethostname(char *name, int namelen);
//Returns: 0 if OK, −1 on error

下面的程序获取系统信息和主机信息:

#include <stdio.h>
#include <sys/utsname.h>
#include <unistd.h>

int main(int argc,char* argv[])
{
    struct utsname buf;
    char name[128];

    if(uname(&buf))
    {
        printf("get sys info faild:\n");
        return -1;
    }

    if(gethostname(name,128))
    {
        printf("get hostname failed\n");
        return -1;
    }

    printf("system name:%s,node name:%s,release:%s,version:%s,hardware identifier:%s\n",            buf.sysname,buf.nodename,buf.release,buf.version,buf.machine);

    printf("hostname:%s\n",name);

    return 0;
}

时间相关

UNIX使用UTC时间而不是本地时间,自动转换夏令时,时间和日期在一起表示,获取日历时间:

#include <time.h>
time_t time(time_t *calptr);
Returns: value of time if OK, −1 on error

更高精度的时间处理:

#include <time.h>

       int clock_getres(clockid_t clk_id, struct timespec *res);

       int clock_gettime(clockid_t clk_id, struct timespec *tp);

       int clock_settime(clockid_t clk_id, const struct timespec *tp);

      // Link with -lrt (only for glibc versions before 2.17).
// clock_gettime(),  clock_settime()  and  clock_getres() return 0 for success, or -1 for failure

clk_id取值如下:

CLOCK_REALTIME   //real system time

CLOCK_MONOTIME //real system time without negative jumps

CLOCK_PROCESS_CPUTIME_ID //CPU time for calling process

CLOCK_THREAD_CPUTIME_ID  //CPU time for calling thread

clock_gerres获取时间精度,clock_gettime获取更精确的时间,clock_settime设置时间,需要特权。

不鼓励用但是大面积用的函数:

#include <sys/time.h>

       int gettimeofday(struct timeval *tv, struct timezone *tz); //tz 一般取NULL不用管

       int settimeofday(const struct timeval *tv, const struct timezone *tz);//tz或者tv为NULL函数不会起作用
//0 sucess,-1 error

时间本地化和UTC使用的结构:

struct tm { /* a broken-down time */
int  tm_sec; /* seconds after the minute: [0 - 60] */
int  tm_min; /* minutes after the hour: [0 - 59] */
int  tm_hour;  /* hours after midnight: [0 - 23] */
int  tm_mday;  /* day of the month: [1 - 31] */
int  tm_mon; /* months since January: [0 - 11] */
int  tm_year;  /* years since 1900 */
int  tm_wday;  /* days since Sunday: [0 - 6] */
int  tm_yday;  /* days since January 1: [0 - 365] */
int  tm_isdst; /* daylight saving time flag: <0, 0, >0 */
};

日历时间转为本地或UTC时间对应的函数:

#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 *restrict buf, size_t maxsize,const char *restrict format,const struct tm *restrict tmptr);
size_t strftime_l(char *restrict buf, size_t maxsize,const char *restrict format,const struct tm *restrict tmptr, locale_t locale);
//Both return: number of characters stored in array if room, 0 otherwise

字符串转化为时间结构:

#include <time.h>
char *strptime(const char *restrict buf, const char *restrict format,struct tm *restrict tmptr);
//Returns: pointer to one character past last character parsed, NULL otherwise

看一个综合的小程序:

#include <stdio.h>
#include <time.h>
#include <sys/time.h>

int main(int argc,char* argv[])
{
    time_t curtime;
    struct tm* st_tm;
    struct timespec res;
    char buf[128];

    curtime = time(NULL);

    printf("big value time:%lld\n",(long long)curtime);

    if(curtime == -1)
    {
        printf("get curtime failed\n");
        return -1;
    }

    if(clock_gettime(CLOCK_REALTIME,&res))
    {
        printf("get high resolution time failed\n");
        return -1;
    }

    if((st_tm = localtime(&curtime))==NULL)
    {
        printf("gettimeofday failed\n");
        return -1;
    }

    if(strftime(buf,128,"%F %T",st_tm)== 0)
    {
        printf("format time failed\n");
        return -1;
    }

    printf("now:%s\n",buf);

    if(!strptime(buf,"%F %T",st_tm))
    {
        printf("convert time back failed\n");
        return -1;
    }

    curtime = mktime(st_tm);

    printf("backed time:%lld\n",(long long )curtime);

    return 0;

}
时间: 2024-12-14 20:33:30

UNIX系统文件的相关文章

Unix系统的umask函数

Unix系统文件及其权限简介 在Unix系统中,所有文件类型都有访问权限.文件类型分为:普通文件(regular file),目录文件(directory file),块特殊文件(block special file),字符特殊文件(character special file),FIFO,套接字(socket),符号链接(symbolic link).下面分别对它们进行简单的介绍: 普通文件(regular file) 这种文件包含了某种形式的数据,至于是文本还是二进制,Unix内核并不关心.

Unix系统后门技术指南

Unix系统后门技术指南 原文:http://ouah.org/backdoors.html 翻译:http://blog.csdn.net/nixawk 简介 黑客攻入系统后,面临一项艰巨的任务----保留对系统的访问权限.为了获取服务器固定的访问权限,入侵者必须知道服务器的所有弱点.这不是一件容易的事.后门或 木马,能够让黑客长期享有目标主机的访问权限.不过,这不能一概而论;后门可以做很多不同的事情,但它们的主要目的是保持对受限区域的访问权限.后门(又名,暗门)与木马之间存在着差异:黑客攻入

Android 安全机制(1)uid 、 gid 与 pid

1.概述 Android 安全机制来源于Linux,并且以Linux权限管理为基础,要了解Android的安全机制,需要从linux中的安全机制了解开始,而用户的权限管理又是linux安全机制的最基本的一个组成 2.linux中的用户(UID).组(GID).进程(PID) 在 Linux 中,一个用户 UID 标示一个给定用户.Linux系统中的用户(UID)分为3类,即普通用户.根用户.系统用户. 普通用户是指所有使用Linux系统的真实用户,这类用户可以使用用户名及密码登录系统.Linux

操作系统学习---文件管理

在现代计算机系统中,要用到大量的程序和数据,因内存容量有限,且不能长期保存,故而平时总是把它们以文件的形式存放在外存中,需要时再随时将它们调入内存.如果由用户直接管理外存上的文件,不仅要求用户熟悉外存特性,了解各种文件的属性,以及它们在外存上的位置,而且在多用户环境下,还必须能保持数据的安全性和一致性.显然,这是用户所不能胜任.也不愿意承担的工作.于是,取而代之的便是在操作系统中又增加了文件管理功能,即构成一个文件系统,负责管理在外存上的文件,并把对文件的存取.共享和保护等手段提供给用户.这不仅

操作系统文件管理

在现代计算机系统中,要用到大量的程序和数据,因内存容量有限,且不能长期保存,故而平时总是把它们以文件的形式存放在外存中,需要时再随时将它们调入内存.如果由用户直接管理外存上的文件,不仅要求用户熟悉外存特性,了解各种文件的属性,以及它们在外存上的位置,而且在多用户环境下,还必须能保持数据的安全性和一致性.显然,这是用户所不能胜任.也不愿意承担的工作.于是,取而代之的便是在操作系统中又增加了文件管理功能,即构成一个文件系统,负责管理在外存上的文件,并把对文件的存取.共享和保护等手段提供给用户.这不仅

《鸟哥linux》--第六章课后习题答案

1./bin与/usr/bin目录放置的执行文件有和不同 /bin主要放置在开机时,以及进入单人维护模式还能够被使用的指令,后者是大部分软件提供的指令放置处 2./bin与/sbin目录放置的执行文件有何不同之处 /bin放置一般用户惯用指令,/sbin则是系统管理员才会使用的指令,同上参考/usr/bin,/usr/sbin 3.哪几个目录不能够与根目录放置到不同partition?并说明该目录所放置的数据为何? /etc(配置文件)./bin(一般身份可用执行文件),/dev(装置档案)./

Python网络编程篇之socket

1 socket 插座?呵呵,想多了,翻译过来意思是套接字! A network socket is an internal endpoint for sending or receiving data at a single node in a computer network. Concretely, it is a representation of this endpoint in networking software (protocol stack), such as an entr

UID, EUID, SUID, FSUID

摘自:https://blog.csdn.net/wh8_2011/article/details/50825340 UID, EUID, SUID, FSUID 2016年03月08日 10:40:02 -鸣人- 阅读数:2267 标签: linux 更多 个人分类: Linux 内核 前 言 real user ID (uid): 实际用户ID,指的是进程执行者是谁effective user ID (euid): 有效用户ID,指进程执行时对文件的访问权限saved set-user-ID

c语言基础----文件

在 C 语言中 '\' 一般是转义字符的起始标志,故在路径中需要用两个 '\' 表示路径中目录层次的间隔,也可以使用 '/' 作为路径中的分隔符. 文件按其逻辑结构可分为:记录文件和流式文件.而记录文件又可分为:顺序文件.索引文件.索引顺序文件及散列文件等. 流是磁盘或其它外围设备中存储的数据的源点或终点.流按方向分为:输入流和输出流.从文件获取数据的流称为输入流,向文件输出数据称为输出流. 流按数据形式分为:文本流和二进制流.文本流是 ASCII 码字符序列,而二进制流是字节序列. 文本文件与