命令控制程序且能获取全部的完整的字符串

功能:
能够实现命令控制且能获取命令后面全部的完整的字符串(含带空格的)

/*
*gcc -o getopt getopt.c
*./getopt --help
*./getopt -h
*/

#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#include <syslog.h>
#include <unistd.h>
#include <time.h>
#include <string.h>

#include <sys/socket.h>
#include <netinet/in.h>

#include <arpa/inet.h>
#include <sys/types.h>

#include <fcntl.h>

#define  VERSION   0                        /*version, 当前为0 -v*/

char *short_opts = "hvn:r:s:d:l:i:m:u:a:";

struct option long_options[] = {
    {"help",          no_argument,       NULL, 'h'},
    {"version",       no_argument,       NULL, 'v'},
    {"process_num",   required_argument, NULL, 'n'},
    {"send_rate",     required_argument, NULL, 'r'},
    {"log_size",      required_argument, NULL, 's'},
    {"log_data",      required_argument, NULL, 'd'},
    {"log_level",     required_argument, NULL, 'l'},
    {"log_id_enable", required_argument, NULL, 'i'},
    {"model_name",    required_argument, NULL, 'm'},
    {"device_num",    required_argument, NULL, 'u'},
    {"server_addr",   required_argument, NULL, 'a'},
    {NULL,            0,                 NULL,  0}
};

typedef struct syslog_command syslog_command_t;

typedef struct
{
    int  process_num;                     /*进程数 -n*/
    int  send_rate;                       /*发送时间间隔,多少ms发送一次 -r*/
    int  log_size;                        /*每条log字节数 -s*/
    char log_data[256];                   /*每条log的内容 -d*/
    int  log_level;                       /*日志级别 -l*/
    int  log_id_enable;                   /*每条log的序号标识 -i*/
    char model_name[128];                 /*模块名称 -m*/
    int  device_num;                      /*子设备个数 -u*/
    char server_addr[50];                 /*服务器地址 -a*/
    int  (*write)(syslog_command_t *command);
}syslog_command;
/*获取随机数*/
void genRandomString(char* buff, int length)
{
    char metachar[] = "abc.defghij,klmn opqr[]stu=vwxyz+01234()5!6789";
    int i = 0;
    srand((unsigned)time(NULL));  //用时间做种,每次产生随机数不一样

    for (i = 0; i < length; i++)
    {
        buff[i] = metachar[rand() % 46];
    }
    buff[length] = '\0';
}

int mylog(syslog_command *command)
{
    openlog(command->model_name, LOG_CONS | LOG_PID, 128);
    //printf("1\n");
    send_syslogd(command->log_data, command);

    return 0;
}

int fork_num(int num, syslog_command *command)
{
    int status,i;

    for (i = 0; i < num; i++)
    {
        status = fork();
        if (status == 0 || status == -1) break;//每次循环时,假设发现是子进程就直接从创建子进程的循环中跳出来。不让你进入循环,这样就保证了每次仅仅有父进程来做循环创建子进程的工作
    }

    if (status == -1)
    {
        printf("error in fork!");//error
    }
    else if (status == 0) //每一个子进程都会运行的代码
    {
        command->write(command);
    }
}

int init_command(syslog_command *command)
{
    command->process_num = 20;
    command->send_rate = 1000 * 100;
    command->log_level = 6;
    command->log_id_enable = 1;

    strcpy(command->log_data, "hello world!, test logger ok");
    command->log_size = strlen(command->log_data);

    strcpy(command->model_name, "mylog");
    command->device_num = 0;
    return 0;
}
/*次函数用于获取命令后面携带的带空格的字符串*/
int get_command_string(char *data, int argc,char **argv)
{
    int i = 0;

    for (i = 0;; i++)
    {
        if (optarg == argv[argc - 1] || *optarg == '-')
        {
            while(*argv[argc - 1] != '\0')
            {
                data[i] = *argv[argc - 1];
                *argv[argc - 1]++;
                i++;
            }
            break;
        }
        else
        {
            data[i] = *optarg;

            if (*optarg == '\0')
            {
                data[i] = ' ';
            }
            optarg++;
        }
    }
    return i;
}

int sock_tcp_connect()
{
    int sock = -1;

    sock = socket (AF_INET, SOCK_STREAM, 0);
    if (sock < 0)
    {
        printf ("SOCKET error. /n");
        return -1;
    }
    printf("sock tcp ok\n");

    return sock;
}

int sock_tcp_close(int sockfd)
{

    if (sockfd > 0)
    {
        close(sockfd);
        sockfd = -1;
    }

    printf("sock_tcp_close\n");
    return 0;
}
/*将嵌套字设为非阻塞的*/
int setnonblocking(int fd, int nonblocking)
{
    int flags, newflags;

    flags = fcntl(fd, F_GETFL, 0);
    if (flags < 0) {
        perror("fcntl(F_GETFL)");
        return -1;
    }
    if (nonblocking)
        newflags = flags | (int) O_NONBLOCK;
    else
        newflags = flags & ~((int) O_NONBLOCK);
    if (newflags != flags)
    {
        if (fcntl(fd, F_SETFL, newflags) < 0)
        {
            perror("fcntl(F_SETFL)");
            return -1;
        }
    }

    return 0;
}

int sock_tcp_write(int sockfd, syslog_command *command)
{
    int ret = -1;
    int err = 0;
    socklen_t  errlen   = sizeof(err);
    char buf[BUFSIZ];
    time_t time_s = 0, time_ns = 0, time_now = 0, time_long = 0;
    struct tm *tm;

    //printf("%s\n" , command->log_data);

    snprintf(buf, sizeof(buf), "%s %s%s", "<134>Nov  2 17:05:58 mylog[1233]:", command->log_data, "\n");
    printf("Local buf is %s/n", buf);
    //strcpy(buf, "hello world!, test logger\n");

    for (;;)
    {
        usleep(command->send_rate);
        ret = send(sockfd, buf, strlen(buf), 0);
    }

    return 0;
ERROR:
    printf("====to close\n");
    sock_tcp_close(sockfd);
    return -1;
}

int sock_tcp(syslog_command *command)
{
    int ret = -1, sockfd = -1;
    struct sockaddr_in server_addr;

    sockfd = sock_tcp_connect();

    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(514);
    server_addr.sin_addr.s_addr = inet_addr(command->server_addr);
    //printf("0x%08x\n" , inet_addr(command->server_addr));
    //printf("%s\n" , command->server_addr);

    ret = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
    if (ret < 0)
    {
        perror("client : connect error\n");
        goto ERROR;
    }
    printf("sock tcp connected\n");

    sock_tcp_write(sockfd, command);

    return 0;
ERROR:

    sock_tcp_close(sockfd);
    return ret;
}

int main(int argc,char **argv)
{
    int opt;
    char *l_optarg;
    syslog_command command;
    char data[256] = {0};

    init_command(&command);

    while((opt = getopt_long(argc , argv, short_opts,  long_options, NULL)) != -1)
    {
        switch(opt)
        {
            case 'h':
                printf("\nOptions:"
                       "\n        -h     help"
                       "\n        -v     version"
                       "\n        -s     Each log bytes(Content randomly generated)"
                       "\n        -n     Number of processes"
                       "\n        -r     Send time interval(ms)"
                       "\n        -d     The content of log"
                       "\n        -l     Log level(0-6)"
                       "\n        -i     Enable serial number(0-unable, 1-enable)"
                       "\n        -m     The name of the module"
                       "\n        -u     Child device num(0-8)"
                       "\n        -a     Server addr(x.x.x.x)"
                       "\n"
                      );
                break;
            case 'v':
                printf("current version is %d\n", VERSION);
                break;
            case 's':
                command.log_size = atoi(optarg);
                genRandomString(data, command.log_size);
                strcpy(command.log_data, data);
                printf("%d\n" , command.log_size);
                break;
            case 'n':
                command.process_num = atoi(optarg);
                printf("%d\n" , command.process_num);
                break;
            case 'r':
                command.send_rate = atoi(optarg) * 1000;
                printf("%d\n" , command.send_rate/1000);
                break;
            case 'd':
                command.log_size = get_command_string(data, argc, argv);
                strcpy(command.log_data, data);
                break;
            case 'l':
                command.log_level = atoi(optarg);
                printf("%d\n" , command.log_level);
                break;
            case 'i':
                command.log_id_enable = atoi(optarg);
                printf("%d\n" , command.log_id_enable);
                break;
            case 'm':
                get_command_string(data, argc, argv);
                strcpy(command.model_name, data);
                break;
            case 'u':
                command.device_num = atoi(optarg);
                printf("%d\n" , command.device_num);
                break;
            case 'a':
                strcpy(command.server_addr, optarg);
                printf("%s\n" , command.server_addr);
                break;
        }
    }

#if 0
    sock_tcp(&command);
#else
    if (command.device_num > 0)
    {
        command.write = sock_tcp;
        fork_num(command.device_num, &command);
    }
    else
    {
        command.write = mylog;
        fork_num(command.process_num, &command);
    }
#endif
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值