标签:
/* write用于登录到几台主机上两个用户直接进行通信 mesg y/n 用于设置是否接收write的消息 格式:write username terminal-line 例如:write 123 tty1 write 123 /dev/tty1 此时制定用户与终端进行通信 write 123 此时程序访问utmp文件,获得获取登录的用户名为123的终端,若终端为多个,则向访问到的最后一个终端发信 输入EOF字符,终止进程 */ #include <stdio.h> #include <string.h> #include <utmp.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #define NUMNAME 30 // 存放终端名的长度 #define NUMMES 50 //接受消息缓冲区的长度 int main(int argc, char* argv[]) { char name[NUMNAME]= ""; //存放用户名 char writeto[NUMNAME] = "/dev/"; //存放终端名 struct utmp buf; int fd; int num, num_utmp, ch; char mes[NUMMES]; num = 0; if (argc == 1) { fprintf(stderr, "usage: write user [tty]"); exit(1); } strcpy(name, argv[1]); if (argc == 3) { //兼容/dev/tty1 和tty1两种参数模式,做兼容处理 if (!strncmp(argv[2], writeto, 5)) strcat(writeto, &argv[2][5]); else strcat(writeto, argv[2]); num++; } else { //遍历utmp文件,获得此时登录机器的用户及终端 if ((fd = open("/var/run/utmp", O_RDONLY)) == -1) { perror("open error"); exit(1); } num_utmp = sizeof(struct utmp); while (read(fd, &buf, num_utmp) == num_utmp) { if (!strcmp (buf.ut_user, name)&&strcmp(buf.ut_line, ":0")) { if (num > 0) writeto[5] = ‘\0‘; strcat(writeto, buf.ut_line); num++; } } close(fd); } //最后writeto参数均为/dev/tty 种形式 if (num == 0){ fprintf(stderr, "no destination:%s\n", name); exit(0); } if (num >1) fprintf(stdout, "more then 1 tty, chose: %s\n", writeto); if ((fd = open(writeto, O_WRONLY)) == -1) { perror("open error"); exit(1); } /* 为相应接受到EOF字符,终止进程,采用getc函数,按字节接收字符,通过write函数,按行写入到目的终端 若接收‘\n‘ 或EOF,则write一次。EOF同时终止程序 */ while (1) { for (num =0;num < NUMMES ;num++) { ch=getc(stdin); mes[num] = ch; if (ch == ‘\n‘ || ch == EOF) break; } if (ch == EOF) { if (num != 0) mes[num++] = ‘\n‘; mes[num] = ‘E‘; mes[++num] = ‘O‘; mes[++num] = ‘F‘; mes[++num] = ‘\0‘; } if (write(fd, mes, num+1) != (num+1)) { perror("write error"); exit(1); } if (ch == EOF) break; } }
执行文件需要设置权限位,才能和系统提供的write命令,运行结果完全一致。否则,在是否有写权限的问题上存在偏差。
依次执行命令:chown root write 用户ID设置为root
chgrp tty write 组ID设置为tty
chmod g+s write 组权限设置set-group-ID位
总结:
1、设置权限位,否则程序运行起来与系统wirte命令结果有较大出入。
chmod g+s write 组权限设置set-group-ID位,非常重要
2、字符串如果越界会出现非常奇怪的错误,且很难察觉,所以字符一定预留足够的长度。此处浪费大量时间。
标签:
原文地址:http://my.oschina.net/u/2313065/blog/475843