自己动手写shell命令之write

Linux下write命令允许用户跟其他终端上的用户对话。用c语言实现shell命令write,代码如下:

#include	<stdio.h>
#include	<fcntl.h>
#include	<unistd.h>
#include	<utmp.h>
#include	<pwd.h>
#include	<sys/types.h>
#include	<stdlib.h>
#include	<sys/stat.h>
#include	<time.h>

char * get_terminal_name(char *);
char * get_terminal_name_by_user_name(char *);
void hello();

int main(int argc, char * argv[]) {
	int fd;
	char buffer[1024];
	char * terminal_name;
	if (argc != 2) {
		printf("write usage: write [ttyname|username]");
		return 1;
	}
	terminal_name = get_terminal_name(argv[1]);
	if(terminal_name == NULL)
	{
		printf("get terminal name error\n");
		return 1;
	}
	//printf("terminate_name:%s", terminal_name);

	fd = open(terminal_name,O_WRONLY);
	hello(fd);

	while(fgets(buffer,1024,stdin) != EOF)
	{
		write(fd,buffer,strlen(buffer));
	}
	close(fd);
	return 0;
}

void hello(int fd) {
	char greeting[1024];
	struct passwd * passwd_pointer;
	time_t now;
	char host[255];
	gethostname(host, 255);
	time(&now);
	passwd_pointer = getpwuid(getuid());
	sprintf(greeting, "Message from %s@%s on %s at %5.5s ...\n",
			passwd_pointer->pw_name, host, ttyname(0), ctime(&now) + 11);
	write(fd,greeting,strlen(greeting));
}

char * get_terminal_name(char * user_input) {
	char terminal_name[255];
	struct stat stat_buffer;
	if (lstat(user_input, &stat_buffer) != -1) {
		if (S_ISCHR(stat_buffer.st_mode)) {
			return user_input;
		}
	}
	return get_terminal_name_by_user_name(user_input);
}

char * get_terminal_name_by_user_name(char * user_name) {
	struct utmp * utmp_pointer;
	setutent();
	int number = 0;
	char * result = (char *) malloc(sizeof(char) * 255);
	char *mytty = ttyname(0); /* begins "/dev/" */
	char *ttydev = mytty + strlen("/dev/");
	printf("%s\n", mytty);

	while ((utmp_pointer = getutent()) != NULL) {
		if (strcmp(user_name, utmp_pointer->ut_user) == 0
				&& utmp_pointer->ut_type == USER_PROCESS
				&& strcmp(utmp_pointer->ut_line, ttydev) != 0
				&& utmp_pointer->ut_line[0] != ':') {
			number++;
			//printf("%s\n", utmp_pointer->ut_line);
			if (number == 1) {
				strcpy(result, "/dev/");
				strcat(result, utmp_pointer->ut_line);
			}
		}
	}
	endutent();
	if (number > 1)
		printf("warning:%s is logged in %d different terminals,using %s\n",
				user_name, number, result);
	if(number == 0)
		return NULL;
	return result;
}

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。