一种远程管理Linux系统工具的设计与实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一种远程管理Linux系统工具的设计与实现
摘要
现在,Linux已经是应用比较广泛的操作系统之一,在其系统中有很多的服务。

为了实现远程配置和管理Linux中的各种服务,需要有一种远程管理Linux 系统的工具软件,Webmin就是一种较好的B/S模式软件,而该课题以C/S模式实现。

该工具主要功能实现对Linux系统用户和组的添加、修改和删除;对系统应用服务(如:DNS、FTP、Apache、系统启动服务管理)进行管理和配置,这些服务的远程配置主要是通过修改服务配置文本文件来实现的。

该远程管理工具选用C/S模式设计,在客户端,采用GTK编程来实现操作界面;在服务器端,选用Linux系统的文件调用函数来读写配置文件中的数据;采用Sock TCP 编程来实现客户端和服务端之间的数据通信。

通过系统测试后,完成预期的目标,但是需要进一步完善程序和考虑安全性后,方可应用于实际的远程管理。

关键词:Linux;系统服务;C/C++;GTK;系统调用;Socket
The Design and Implementation of a Remote Management
Tool for Linux
Abstract
The operating system of Linux has become one of the most popular operating systems nowadays. It provides many kinds of service. In order to configure and manage the service remotely, the tool of remote management of the operating system of Linux is needed. Webmin is a good tool of software based on the model of B/S. This design is implemented based on the model of C/S. The main functions of the system include addition, modification, deletion of users and groups of Linux operating system and configuration and management of the service of application of the system, such as the DNS, FTP, Apache and the management of booting service. The remote management of service is implemented by modifying the files of configuration. The model of C/S is selected by this system. In the Client, the operating interface is made by the programming of GTK. In the Server, the functions of transferring of files of Linux operating system are used to write and read the data of the configuration files. The communication of Client and Server is implemented by the programming of Sock TCP. The testing demonstrates that the system has reached the prospective goal. But lots of improvements should be made and the problems of security should be considered more. After being modified and perfected, the system can be used to manage the system remotely.
Key words: Linux;System Servers;C/C++;GTK;System Call;Socket
目录
论文总页数:33页
1 引言 (1)
1.1课题背景 (1)
1.2国内外研究现状 (1)
1.3本课题研究的意义 (1)
1.4本课题的研究方法 (1)
2 GTK编程 (1)
2.1GTK简介 (1)
2.2常用的GTK构件 (3)
3 LINUX系统调用 (6)
3.1L INUX系统文件 (6)
3.2如何从文件中读取数据 (6)
3.3进程和线程的使用 (7)
4 基本的套接口编程 (7)
4.1概述 (7)
4.2简单的网络编程 (8)
5 程序设计和流程图 (10)
5.1设计思路 (10)
5.2服务程序 (10)
5.2.1流程设计 (10)
5.2.2功能模块 (11)
5.3客户程序 (20)
5.3.1设计思路 (20)
5.3.2程序设计 (20)
6 系统测试 (30)
结论 (32)
参考文献 (33)
致谢 (34)
声明............................................................................................................错误!未定义书签。

1引言
1.1课题背景
Linux是目前应用最广泛的操作系统之一,基于Linux系统的网络服务软件(如FTP、Apache、DNS、SendMail)的功能也很强大。

但是现在能够统一对这些服务进行管理的软件却很少的。

本课题为减轻系统管理员的工作量而提供了一些简单的系统服务的管理和查看工具。

1.2国内外研究现状
Linux是现在开源项目的代表,很多大的硬件厂商也在支持Linux的发展。

而且Linux平台上的服务软件也是越来越多了。

现在Linux已经进入到企业级应用,Webmin是一种基于B/S模式的远程管理Linux系统的软件工具。

1.3本课题研究的意义
本课题是为了给系统管理员提供一种远程管理Linux中某些主要服务的工具软件,完成服务配置管理和查看一些重要的数据。

由于Linux是开源项目的代表,对Linux的学习有助于对计算机系统和软件理论知识的提高。

通过该课题的设计和实现,既解决远程管理Linux系统,又让自己掌握了一些Linux系统编程和Sock编程能力。

1.4本课题的研究方法
本课题主要是对网络配置、GTK库、Linux系统调用和网络编程方面的研究。

采用C/S模式,在客户端采用GTK函数实现用户界面的编写,在服务器端通过Linux的系统调用,来实现本地服务配置,然后再通过Sock编程来实现服务器和客户端的通信,传递配置内容和服务指令。

2GTK编程
2.1GTK简介
GTK(GIMP Toolkit,GIMP工具包)是一个用于创造图形用户接口的多平台工具。

它包含有基本的空间和一些很复杂的控件:例如文件选择控件。

GTK最初是GIMP(GNU图形处理程序)开发的控件集合,然后它不断扩展,直到今天被用于大量的应用程序当中。

从根本上来说,主循环是由glib实现的。

Gtk将glib主循环连接到Gdk 的X服务器,并提供一个方便的接口。

Gtk分别用gtk_main()函数和gtk_main_quit()函数来运行主循环和退出主循环,当系统调用了gtk_main()函数后,由于gtk_main()函数可以递归调用,所以需要调用gtk_main_quit()函数才能退出gtk。

gtk_main()函数的所有功能都是监视Gtk程序和与X服务的连接,对同样的时间队列起作用。

gtk_main()函数用于阻塞该进程直到满足某些条件。

所有
的Gtk程序都用这个技巧使应用程序正在运行时main()函数被阻塞,直到用户通过点击鼠标或键盘来产生一个信号,并通过该信号来调用相应的回调函数。

GTK是一个时间驱动工具包,它将在gtk_main()函数中一直等待,直到某个事件的发生或控制权被交给相应的函数。

(1)信号
控制权的传递是使用“信号”的方法。

一旦事件发生,比如鼠标器按钮被按下,被按下的构件(按钮)将引发适当的信号。

有一些信号是大多数构件都具备的,比如destory,还有一些是某些构件专有的,比如在按扭的toggled 信号。

要让一个按钮执行一个操作,我们需要写一段信号处理程序,以捕获它的信号,然后调用相应的回调函数。

这由类似以下所示的函数实现:
Gint gtk_signal_connect(GtkObject *object,
Gchar *name,
GtkSignalFunc func,
gpointer func_data );
上面函数的第3个参数为回调函数,它的形式通常是:
void callback_func( GtkWidget *widget, gpointer callback_data );
(2)事件
除了上面的信号机制外,还有一些和X事件机制相对应的事件。

回调函数也可以和这些事件连接起来应用。

将回调函数连接到X的某一个事件,需要使用gtk_signal_connect函数,并使用事件名称作为命名参数。

事件的回调函数与信号的回调函数在形式上略有不同:
Void func(GtkWidget *widget,
GdkEvent *event,
gpointer callback_data );
GdkEvent是C中的联合体结构,其类型依赖于发生的事件。

要想知道哪一个事件已经引发,可以查看类型参数,因为每个可能的可选事件都有一个反映引发事件的类型参数。

将回调函数与一个事件连接起来,需要使用以下形式的函数:gtk_signal_connect( GTK_OBJECT(button),
"button_press_event"
GTK_SIGNAL_FUNC(button_press_callback),
NULL) ;
这里假定button是一个按钮构件。

现在,当鼠标移动到按钮上方,鼠标按钮按下时,将调用button_press_callback函数。

回调函数可以作如下声明:
static gintbutton_press_callback( GtkWidget *widget,
GdkEventButton *event,
gpointer data);
2.2常用的GTK构件
GTK构件可以分为两种。

一种有一个相关联的GdkWindow窗口,另一种没有。

绝大多数构件都是第一种构件,并且可以显示在GdkWindow窗口。

(1)GtkWindow构件
GtkWindow构件是最大的容器,它实际就是一个窗体构件。

但是它只可以容纳一个子构件,所以要让GtkWindow能容纳更多的构件必须使用布局控件来布局。

用下面的函数创建新窗口:
GtkWidget* gtk_window_new (GtkWindowType type);
用下面的构件向窗口中添加子构件:
gtk_container_add (GTK_CONTAINER (window), widget);
(2)组装构件
组装构件通常是直接从GtkContainer派生而来。

这些构件可以有多个子构件,它们的作用就是管理布局。

“管理布局”意味着这些容器为它们容纳的子构件分配大小尺寸和位置。

例如,GtkVBox将它的子构件在一个垂直的栈内排列。

GtkTable构件可以让构件在一个表格上根据单元格定位。

GtkTable(表格构件)是很常用的用于定位的构件。

我们用表格构件创建一个网格,把构件放在网格里。

构件可以在网格中占据任意多个格子。

用gtk_table_new创建一个表格构件:
GtkWidget *gtk_table_new( gint rows,gint columns,gint homogeneous);
要将构件放到表格中,可以使用下列函数:
void gtk_table_attach(GtkTable *table,
GtkWidget *child,
gint left_attach,
gint right_attach,
gint top_attach,
gint bottom_attach,
gint x options,
gint yoptions,
gint xpadding,gint ypadding );
(3)按钮构件
GtkButton(普通按钮构件)是应用程序中使用最广泛的构件。

它一般用于当
用户点击它时执行某个动作,其使用和创建也相当简单。

可以用gtk_button_new_with_label()创建带标题的按钮。

按钮创建以后就可以用上面所讲述的GTK信号和回调函数或事件机制来实现,当按扭按下或有其他操作时候的回调函数来响应相应的函数或事件。

(4)文本构件
GtkText(文本构件)允许多行显示或编辑文本。

它支持多种颜色以及多种字体的文本,允许它们以任何需要的形式混合显示,还有许多与Emacs兼容的文本编辑命令。

文本构件支持完全的剪切/粘贴功能,还包括双击选择一个单词和单击选择整行的功能。

创建新Text构件只有一个函数:
GtkWidget *gtk_text_new( GtkAdjustment *hadj,GtkAdjustment *vadj );
文本构件有两个主要用途:允许用户编辑一段文本,或向用户显示多行文本。

为了在两种操作模式之间进行切换,文本构件有以下函数:
void gtk_text_set_editable( GtkText *text,gint editable );
为了在当前插入点插入文本,可以使用gtk_text_insert函数。

插入时可以指定文本的背景色、前景色和字体。

void gtk_text_insert(GtkText *text,
GdkFont *font,
GdkColor *fore,
GdkColor *back,
const char *chars,
gint length );
(5)标签构件
GtkLabel(标签构件)是GTK中最常用的构件之一,实际上它很简单。

因为没有相关联的X窗口,标签构件不能引发信号。

如果需要引发信号,可以将它放在一个事件盒构件中,或放在按钮构件中。

用以下函数创建新标签构件:GtkWidget *gtk_label_new(char *str );
唯一的参数是要由标签显示字符串。

创建标签构件后,要改变标签内的文本,用以下函数:
void gtk_label_set_text( GtkLabel *lacbel,char *str );
第一参数是前面创建的标签构件(用GTK_LABEL()宏转换),第二个参数是新字符串。

如果需要,新字符串所需的空间会做自动调整。

在字符串中放置换行符,可以创建多行标签。

(6)笔记本构件
GtkNotebook(笔记本构件)是互相重叠的页面集合,每一页都包含不同的信息,且一次只有一个页面是可见的。

该构件在GUI(图形用户接口)编程中很常用。

要说明大量的相关信息,同时把它们分别显示时,使用这种构件是一个很好的方法。

许多应用程序的“选项”对话框都使用了这个构件。

用下面的函数可以创建新笔记本构件。

GtkWidget *gtk_notebook_new( void );
向笔记本构件中添加页面,主要有两种方法,而且非常相似的,如下:
●在笔记本构件中追加页面:
void gtk_notebook_append_page(GtkNotebook *notebook,
GtkWidget *child,
GtkWidget *tab_label );
●在笔记本构件中前插页面:
void gtk_notebook_prepend_page(GtkNotebook *notebook,
GtkWidget *child,
GtkWidget *tab_label );
其中child参数是放在笔记本构件上的子构件,tab_label是要添加的页面的标签。

子构件必须分别创建,一般是一个容器构件,比如说表格构件。

(7)分栏列表构件
GtkCList(分栏列表构件)是GtkList(列表构件)的替代品,但它提供更多的特性。

分栏列表构件是多列列表构件,它有能力处理数千行的信息。

每一列都可以有一个标题,而且可以是活动的,还可以将函数绑定到列选择上。

创建GtkClist构件的方法和创建其他构件的方法类似。

因为GtkCList可以有多列,因而在创建它之前,必须确定要创建的列表的列数。

创建分栏列表的函数:GtkWidget *gtk_clist_new ( gint columns );
GtkWidget *gtk_clist_new_with_titles(gint columns,
gchar *titles[] );
创建列表后,需要向构件中添加一些要显示和操作的数据,用下面的函数可以向列表中添加一些数据行:
gint gtk_clist_prepend( GtkCList *clist,gchar *text[] );
gint gtk_clist_append( GtkCList *clist,gchar *text[] );
用下面的函数可以删除一些数据行:
void gtk_clist_remove( GtkCList *clist,gint row );
与其他构件一样,GtkCList有一些信号供我们使用。

GtkCList构件是从容器构件GtkContainer派生的,它有容器所具有的一些信号,还有下面这些附加信号:
select_row:选中一行时引发,该信号传递信息,依次是GtkCList *clist、gint row、gint column、GtkEventButton *event。

unselect_row:用户对一行取消选择,引发这个信号。

传递的信息与上一个信号一样。

click_column:选中某一列时引发,传递信息,依次是: GtkCList *clist、gint column。

所以,要将一个回调函数连接到select_row信号上,回调函数应该像下面这样:
void select_row_callback(GtkWidget *widget,gint row,gint column, GdkEventButton *event,gpointer data);
回调函数用下面的形式连接到信号:
gtk_signal_connect(GTK_OBJECT( clist),
"select_row",
GTK_SIGNAL_FUNC(select_row_callback),
NULL);
以上只是简单介绍了本课题在客户端界面编写的时候可用到的GTK库函数,但实际的GTK比上面的操作还要复杂得多。

3Linux系统调用
3.1Linux系统文件
在Linux中最主要的资源就是文件,很多设备都是以文件形式存在的,所
以大多数输入/输出都要通过文件读写来实现。

也就是说通过一个单一的接口就
可以处理外围设备和程序之间的通信。

Linux文件类型常见的有:普通文件、
目录、字符设备文件、块设备文件、符号链接文件等。

很多系统服务和应用服
务的配置文件都是以普通文件的形式存在,这些文件很容易通过Linux的系统
调用来配置和修改,也可以用文档文件的修改方式来修改。

3.2如何从文件中读取数据
Linux文件读取有两种方法:一种是通过C语言的标准库函数调用来完成;另一种是通过对Linux的系统调用来完成。

文件读取分3步完成:第一步是打
开要读取的文件;第二步是把文件读取到内存中去;第三步是关闭打开的文件。

●在Linux中打开一个文件可以通过系统调用open()函数来实现:
int fd = open(char *name,int how);
其中参数name是要打开的函数名字;how是打开的方式;返回值-1为错误,成功就返回一个文件描述符。

●Linux系统读取文件内容通过系统调用read()函数来实现,函数原形:
ssize_t numread = read(int fd,void *buff,size_t qty);
第1个参数是打开的文件描述符,第2个参数是存储文件数据的内存地址,第3个参数是读取数据大小。

如果读取成功返回值是读取的字节数,失败就返回-1。

系统调用write()函数将内存中的数据写入到文件中去,函数原形:ssize_t resut = write(int fd,void *buff,zize_t amt);
这个系统将调用buff的数据写到文件中。

第1个参数是打开的文件描述符;第2个参数是要写入文件数据的内存地址;第3个参数是写入文件的大小。

进程不需要再对文件进行读写操作时,就要关系文件打开的文件。

close()能关闭打开的文件,其函数原形:
int result = close(int fd);
这个系统调用会关闭进程和文件之间的连接。

参数是打开的文件描述符号。

关闭成功返回0,失败返回-1。

3.3进程和线程的使用
(1) Linux进程
Linux进程创建很特别。

很多其他操作都提供了产生进程的机制,在新的进程空间中创建进程,读取可执行文件。

但是Linux不同,它创建的子进程具有和父进程相同的数据、代码段。

父进程和子进程间的区别就是进程的pid不同,其他的都一样:
pid_t result = fork(void)
该函数比较特殊,它返回两次函数值,一次返回值是向父进程返回子进程的PID。

还有一次是返回0(子进程)。

在使用fork()函数创建进程的时候经常父进程等待子进程结束。

系统调用wait(&status)让父进程阻塞直到子进程结束:
pid_t result = wait(&status);
(2) Linux线程
进程为线程提供了运行环境,多个函数可以同时运行,但是他们都是运行在相同的进程中的。

pthread_cearte()函数可以创建一个线程:int pthread_ceate(pthread_t *thread,
pthread_attr_t *attr,
void *(*func)(void*),
void *arg);
4基本的套接口编程
4.1概述
让同一网络的不同计算机的进程能够相互通信,首先要确定这些程序如何
进行通信。

本课题所用的协议是TCP/IP协议。

如果客户和服务器处于同一以太网,如图1所示。

4.2简单的网络编程
(1) socket函数
socket函数功能是创建一个套接口描述符,并且指定希望的通信协议(使用IPV4的TCP,或者使用IPV6的UPD等)。

int socket(int family,int type,int protocol);
其中family参数指明协议族,type参数指明套接口类型,protocol参数为某个协议的常数。

函数调用成功时候返回一个非负的描述符。

(2) connect函数
TCP客户程序用connect函数来发起和TCP服务程序的连接。

这个函数通常是在客户程序中使用。

int connect(int sockfd,
const sgruct sockaddr *servaddr,
socklen_t addrlen);
sockfd是有socket函数返回的一个套接口描述符,第2个和第3个参数分别是一个指向套接口地址结构指针和结构的大小。

当函数调用成功的时候返回0,出错就返回-1。

(3) bind函数
该函数是把一个本地协议地址赋予一个套接口,对于网际协议,协议地址是一个32位的IPV4地址和一个16位的TCP端口号的组合。

int bind(int sockfd,const struct aockaddr *myadd,socklen_t addrlen);
第2个参数是一个指向特定协议的地址结构的指针,第3个参数是该地址结构的长度。

调用成功返回0,错误返回-1。

(4) listen函数
listen函数只能由TCP服务器调用,他完成两件事:
一是当socket函数创建一个套接口时它是一个主动的套接口,该函数就是把它转换成一个被动的套接口
二是该函数规定了为相应套接口排队的最大的连接个数。

int listen(int sockfd,int backlog);
本函数通常都是在调用socket和bind这两个函数之后。

(5) accept函数
int accept(int sockfd,struct sockaddr *cliaddr,socklen_t *addrlen);
参数cliaddr和addrlen用来返回已经连接的客户端的协议地址。

函数返回值为一个非负的描述符表示成功,出错为-1。

这里需要指出的是参数的描述符为监听套接口,就是在等待连接的时候还没有建立连接的套接口,而返回值是连接的新的套接口。

也就是能和客户端通信的套接口。

区分这两个东西是很重要的。

(6)close函数
套接口编程通常都需要一个close函数来关闭套接口,来中断TCP的连接。

int close(int sockfd);
(7)send()函数
当连接建立了后自然就需要数据的传送和接收,send()函数是用来想连接的另外一端发送数据。

int send(int sockfd,void *buf,int len,int flags);
第1个参数是已经连接的套接口的描述符,第2个参数是发送的数据的内存地址,第3个参数是发送数据的大小,第4个参数是选项。

(8)recv()函数
数据发送到接收端了后,就可以用recv()函数来接收由发送端发送过来的数据了。

int recv(int sockfd,void *buf,int len,int flags)
第1个参数是已经连接的套接口的描述符,第2个参数是发送的数据的内存地址,第3个参数是发送数据的大小,第4个参数是选项。

5程序设计和流程图
5.1设计思路
本课题是采用C/S模式。

客户程序功能是界面的编写,并和服务程序通信。

采用GTK编写界面,采用Sock编程实现通信。

服务器程序功能是接收客户程序的数据,并且通过收到的数据来完成系统或应用服务程序文件的配置。

在Linux 中服务配置文件主要是以文本文件的形式存在的,所以通过Linux系统调用很容易修改配置文件,流程如图2。

图2 程序总体流程
5.2服务程序
5.2.1流程设计
服务程序功能有两个:一是监听端口,接收数据和向客户程序发送数据;二是根据客户程序发送过来的数据对文件修改,其流程图如图3所示。

图3显示了服务程序的流程,accept()是监听端口,等待客户程序的连接,连接建立好后init_clinet()函数从配置文件读取服务器的当前配置文件数据,然后再发送到客户程序,让客户程序通过这些数据来初始化界面。

然后再接收客户程序的数据(流程控制字符串),通过判断字符串来控制服务程序的流程(图3中的虚线部分)。

5.2.2功能模块
(1)系统用户管理操作
和客户程序建立了连接,并且收到了user字符串后,服务程序进入系统用户管理操作模块,接着接收客户程序发送过来的数据(字符串),通过数据来判断是对用户的添加、删除、浏览或修改操作。

接收到了“adduser”字符串就进入添加用户流程;接收到“deluser”字符串就进入删除用户流程;接收到“scanuser”字符串就进入了浏览用户流程;接收到“property”字符串就进入到了修改用户流程,系统用户管理操作流程如图4所示。

图4 用户操作流程
对用户的操作是添加、删除和修改用户,Linux 用户都是记录在
到2
/etc/passwd文件中,对用户添加、删除和修改都是通过修改/etc/passwd文件来实现。

/etc/passwd的用户都是按照统一存格式来存储,格式举例如下:terrycheops:x:500:500:terrycheop:/home/terrycheops:/bin/bash
存储中每个字段都用“:”隔开的,第一字段:用户名(也被称为登录名),在上面的例子中,我们看到用户的用户名是terrycheops;第二字段:口令,在例子中我们看到的是一个x,其实密码已被映射到/etc/shadow 文件中;第三字段:用户的ID;第四字段:用户组的ID;第五字段:用户名全称,可选项;第六字段:用户的家目录所在位置,该用户的是/home/terrycheops。

第七字段:用户所用Shell的类型,一般设置为/bin/bash。

程序进入到了添加用户后,接收客户程序传过来要添加的用户信息(用户名、密码、全名)。

把客户程序发送过来的用户密码用MD5算法加密,把加密后的密码和用户其他数据按照/etc/passwd的格式复制到字符串变量(str)中。

用C语言的流的读操作打开文件/etc/passwd,读取/etc/passwd中的每一行,把每次读取的数据都复制到二维数组(temp)中,关闭文件。

再以写的形式打开文件,然后把上面二维数组(temp)的内容写到文件中,最后再把变量(str)写到文件中,这样就实现了用户的添加。

程序进入到了删除用户流程后,接收客户程序要删除用户的用户名。

用C 中流的操作打开文件/etc/passwd,判断读取的数据,当要删除的用户名和读取的用户名一致时就不把这个用户信息复制到二维数组(temp);读取用户名和删除用户名不一样就把读取数据复制到temp中。

然后关闭这个流。

重新以写文件的操作打开文件/etc/passwd,然后把二维数组(temp)中的数据的以流的形式在写入到文件/etc/passwd中,这样就实现了用户的删除。

用户修改过程,接收客户程序发送过来的数据后,把接收的数据格式化复制到str中。

以C语言中流的操作打开并且读取文件/etc/passwd的数据,判断读取的数据,当要修改的用户名和读取的用户名一致时把str数据复制到二维数组(temp);读取用户名和修改的用户名不一致时就把读取数据复制到temp 中。

然后关闭这个流。

重新以写文件的操作打开文件/etc/passwd,然后把二维数组(temp)中的数据以流的形式再写入到文件/etc/passwd中,这样就完成了修改用户的操作
当进入浏览用户的流程后,打开/etc/passwd文件,把文件的数据读取到buff中,再关闭文件,把buff的数据发送的到客户程序,让客户程序显示当前的用户信息。

(2)系统用户组的操作
用户组(Group)配置文件主要有 /etc/group和/etc/gshadow,其中
/etc/gshadow是/etc/group的加密信息文件。

etc/group 文件是用户组的配置文件,内容包括用户和用户组,并且能显示出用户是归属哪个用户组或哪几个用户组,因为一个用户可以归属一个或多个不同的用户组;同一用户组的用户之间具有相似的特征。

对组的操作都是通过修改/etc/group来实现的,主要是对组的添加删除和修改。

进入到组添加流程后,接收客户端发送过来要添加的组的信息,然后把接收的数据格式按照/etc/group存储格式格式化后复制到str中。

然后打开文件/etc/group,读取文件中组的数据复制到二维数组(temp)中,关闭文件。

在打开文件/etc/group把temp的数据写到文件中去,最后把str写入到文件中,关闭文件,这样就实现了组的添加。

组的删除过程,读取客户程序发送过来的数据,然后打开/etc/group文件,读取文件的数据,当读取的数据和发送过来的组名一样,就不把读取数据复制到二维数组(temp)中,其它都把读取的数据复制到temp中,关闭打开的文件。

再次打开文件/etc/group,把temp的数据都写到文件中,关闭文件,这样就完成组的删除操作。

组的修改过程,接收客户端发送过来要添加组的信息,然后把接收的数据格式按照/etc/group存储格式格式化后存复制到str变量中。

然后打开/etc/group文件,读取文件的数据,当读取的数据和发送过来的组名一样,就把str复制到temp中,其它都把读取的数据复制到temp中,关闭打开的文件。

再次打开文件/etc/group,把temp的数据都写到文件中,关闭文件,这样就完成组的修改操作。

浏览组的过程,当程序到了浏览组的流程后,打开/etc/group文件,把文件的数据读取到buff中,再关闭文件,把buff的数据发送的到客户程序。

让客户程序显示当前的用户信息。

用户组操作的流程如图5所示。

相关文档
最新文档