通过消息机制,传送shell结果

大耗子 2020年06月06日 121次浏览

文章链接:https://codemouse.online/archives/2020-06-06202119

common.h

#pragma once

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<errno.h>
#include<string.h>

#define _PATH_ "."
#define _PROJ_ID_ 0x6666
#define _SIZE_ 4096

#define CLIENT_TYPE 1
#define SERVER_TYPE 2

struct msgbuf
{
    long mtype;
    char mtext[_SIZE_];
};

int creat_queue();
int get_queue();

int send_msg(int msgqueue_id,int who,char *msg);
int recv_msg(int msgqueue_id,int want,char out[],int out_len);

int delete_msgqueue(int msgqueue_id);


common.c

#include"common.h"

static int com_creat_queue(int flags)
{
    key_t key = ftok(_PATH_,_PROJ_ID_);
    if(key < 0){
        printf("%d:%s\n",errno,strerror(errno));
        return -1;
    }
    int msg_id = msgget(key,flags);
    if(msg_id < 0){
        printf("%d:%s\n",errno,strerror(errno));
        return -2;
    }
    return msg_id;
}

int creat_queue()
{
    int flags = IPC_CREAT|0666;
    return com_creat_queue(flags);
}

int get_queue()
{
    int flags = IPC_CREAT;
    return com_creat_queue(flags);
}

int send_msg(int msg_id,int who,char *msg)
{
    struct msgbuf _buf;
    memset(&_buf,'\0',sizeof(_buf));
    _buf.mtype = who;
    strcpy(_buf.mtext,msg);
    printf("say : %s\n",_buf.mtext);
    return msgsnd(msg_id,&_buf,strlen(_buf.mtext),0);
}
int recv_msg(int msg_id,int want,char out[],int out_len)
{
    struct msgbuf _buf;
    memset(&_buf,'\0',sizeof(_buf));
    int ret = msgrcv(msg_id,&_buf,sizeof(_buf.mtext),want,0);
    if(ret <= -1)
    {
        printf("%d:%s\n",errno,strerror(errno));
        return -1;
    }
    memset(out,'\0',out_len);
    strcpy(out,_buf.mtext);
    return 0;
}
int delete_queue(int msg_id)
{
    int ret = msgctl(msg_id,IPC_RMID,NULL);
    if(ret < 0){
        printf("%d:%s\n",errno,strerror(errno));
        return -3;
    }
    return 0;
}


main.c

int server()
{
    int msg_id = creat_queue();
    if(msg_id < 0){
        printf("%s\n",strerror(errno));
        return -1;
    }
    char buf[_SIZE_];
	int fd[2];
    int backfd;
    pipe(fd);
    backfd=dup(STDOUT_FILENO);//备份标准输出,用于恢复
	fcntl(fd[0],F_SETFL,FNDELAY);
    while(1)
    {
        //sleep(5);
		
        memset(buf,'\0',sizeof(buf));
        int ret = recv_msg(msg_id,CLIENT_TYPE,buf,sizeof(buf));
        if(ret == 0){
            if(strncasecmp(buf,"quit",4) == 0){
                printf("client leave!\n");
                break;
            }
            printf("client say : %s\n",buf);
        }
		dup2(fd[1],STDOUT_FILENO);  //将标准输出重定向到fd[1]
		system(buf);
		read(fd[0],buf,1024);
		
		dup2(backfd,STDOUT_FILENO);  //恢复标准输出
        send_msg(msg_id,SERVER_TYPE,buf);
    }
    return delete_queue(msg_id);
}
int main()
{
    server();
    return 0;
}