busybox源码剖析(1)

busybox源码剖析(1)—whoami.c

想找个简单的代码来看,学习代码的架构设计,就找到了busybox。先从最早的版本开始看。

whoami命令是获取当前终端的用户名。/etc/passwd文件存储了所有用户名的清单。要注意的是/etc存储的配置文件大多是系统级的配置文件。而whoami想要达到目的,就需要与/etc/passwd文件打交道。

首先来看whoami.c的主体程序:

whoami_main(int argc, char **argv) 2 { 3char user[9]; 4uid_t uid = geteuid();(argc > 1) 7 show_usage(); 8 9 my_getpwuid(user, uid);10if (*user) {11 puts(user);12return EXIT_SUCCESS;13 }, (unsigned) uid);15 }

首先通过geteuid()系统调用获得uid,然后,通过my_getpwuid(user,uid)获得username。

再看my_getpwuid函数。

1 void my_getpwuid(char *name, long uid) 2 { 3struct passwd *myuser; 4 5myuser = getpwuid(uid); 6if (myuser==NULL), (long)uid);strcpy(name, myuser->pw_name);10 }

/etc/passwd中的每条记录都有相同的格式:

name:password:uid:gid:comment:home:shell

每项的具体内容可以查看这里。

struct passwd 结构就对应了这个记录:

1 struct passwd 2 {*pw_passwd;uid_t pw_uid;gid_t pw_gid;*pw_gecos;*pw_dir;*pw_shell;};

我们无法单独得到username,所有,我们必须先得到struct passwd结构。my_getpwuid函数中的getpwuid函数就实现这个功能。

1 struct passwd *getpwuid(uid_t uid) 2 { 3int passwd_fd; 4struct passwd *passwd;((passwd_fd = open(, O_RDONLY)) < 0) 7return NULL;((passwd = __getpwent(passwd_fd)) != NULL)10if (passwd->pw_uid == uid) {11 close(passwd_fd);12return passwd;13 }14 15 close(passwd_fd);16return NULL;17 }

第9行while不断读取/etc/passwd中的条目,找到目标就return。进入到__getpwent中。

1 if ((line_len = read(pwd_fd, line_buff, PWD_BUFFER_SIZE)) <= 0) //field_begin = strchr(line_buff, ); 4if (field_begin != NULL) 5lseek(pwd_fd, (long) (1 + field_begin – (line_buff + line_len)),{ {10if ((line_len = read(pwd_fd, line_buff, PWD_BUFFER_SIZE)) <= 0)11return NULL;)));13lseek(pwd_fd, (long) (field_begin – line_buff) – line_len + 1,14 SEEK_CUR); 15goto restart;16}

得到一个条目的首地址line_buff后,网站空间,香港虚拟主机,就可以parse了。过程很简单。

1 for (i = 0; i < 7; i++) { 2switch (i) {: 4passwd.pw_name = field_begin; 5break;: 7passwd.pw_passwd = field_begin; 8break;:10uid_ptr = field_begin;11break;:13gid_ptr = field_begin;14break;:16passwd.pw_gecos = field_begin;17break;:19passwd.pw_dir = field_begin;20break;:22passwd.pw_shell = field_begin;23break;24 }25if (i < 6) {);27if (field_begin == NULL)28goto restart;;30}

找到符合uid的条目后,虚拟主机,my_getpwuid函数得到username,输出就可以了。

posted on

记忆的屏障,曾经心动的声音已渐渐远去。

busybox源码剖析(1)

相关文章:

你感兴趣的文章:

标签云: