client.c
author viric@llimona
Fri, 13 Apr 2007 20:52:28 +0200
changeset 127 c620eacd7630
parent 117 db479ef293d3
child 146 5e689cb593aa
permissions -rw-r--r--
Fixed the versions in the code.

/*
    Task Spooler - a task queue system for the unix user
    Copyright (C) 2007  LluĂ­s Batlle i Rossell

    Please find the license in the provided COPYING file.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "main.h"

static void c_end_of_job(const struct Result *res);

char *build_command_string()
{
    int size;
    int i;
    int num;
    char **array;
    char *commandstring;
    
    size = 0;
    num = command_line.command.num;
    array = command_line.command.array;

    /* Count bytes needed */
    for (i = 0; i < num; ++i)
    {
        /* The '1' is for spaces, and at the last i,
         * for the null character */
        size = size + strlen(array[i]) + 1;
    }

    /* Alloc */
    commandstring = (char *) malloc(size);
    if(commandstring == NULL)
        error("Error in malloc for commandstring");

    /* Build the command */
    strcpy(commandstring, array[0]);
    for (i = 1; i < num; ++i)
    {
        strcat(commandstring, " ");
        strcat(commandstring, array[i]);
    }

    return commandstring;
}

void c_new_job()
{
    struct msg m;
    char *new_command;

    m.type = NEWJOB;

    new_command = build_command_string();

    /* global */
    m.u.newjob.command_size = strlen(new_command) + 1; /* add null */
    m.u.newjob.store_output = command_line.store_output;
    m.u.newjob.should_keep_finished = command_line.should_keep_finished;

    /* Send the message */
    send_msg(server_socket, &m);

    /* Send the command */
    send_bytes(server_socket, new_command, m.u.newjob.command_size);

    free(new_command);
}

int c_wait_newjob_ok()
{
    struct msg m;
    int res;

    res = recv_msg(server_socket, &m);
    if(res == -1)
        error("Error in wait_newjob_ok");
    if(m.type != NEWJOB_OK)
        error("Error getting the newjob_ok");

    return m.u.jobid;
}

int c_wait_server_commands()
{
    struct msg m;
    int res;

    while (1)
    {
        res = recv_msg(server_socket, &m);
        if(res == -1)
            error("Error in wait_server_commands");

        if (res == 0)
            break;
        if(res != sizeof(m))
            error("Error in wait_server_commands");
        if (m.type == RUNJOB)
        {
            struct Result res;
            /* This will send RUNJOB_OK */
            run_job(&res);
            c_end_of_job(&res);
            return res.errorlevel;
        }
    }
    return -1;
}

void c_wait_server_lines()
{
    struct msg m;
    int res;

    while (1)
    {
        res = recv_msg(server_socket, &m);
        if(res == -1)
            error("Error in wait_server_lines");

        if (res == 0)
            break;
        if(res != sizeof(m))
            error("Error in wait_server_lines 2");
        if (m.type == LIST_LINE)
        {
            char * buffer;
            buffer = (char *) malloc(m.u.line_size);
            recv_bytes(server_socket, buffer, m.u.line_size);
            printf("%s", buffer);
            free(buffer);
        }
    }
}

void c_list_jobs()
{
    struct msg m;

    m.type = LIST;

    send_msg(server_socket, &m);
}

void c_send_runjob_ok(const char *ofname, int pid)
{
    struct msg m;

    /* Prepare the message */
    m.type = RUNJOB_OK;
    m.u.output.store_output = command_line.store_output;
    m.u.output.pid = pid;
    if (command_line.store_output)
        m.u.output.ofilename_size = strlen(ofname) + 1;
    else
        m.u.output.ofilename_size = 0;

    send_msg(server_socket, &m);

    /* Send the filename */
    if (command_line.store_output)
        send_bytes(server_socket, ofname, m.u.output.ofilename_size);
}

static void c_end_of_job(const struct Result *res)
{
    struct msg m;

    m.type = ENDJOB;
    m.u.result = *res; /* struct copy */

    send_msg(server_socket, &m);
}

void c_shutdown_server()
{
    struct msg m;

    m.type = KILL_SERVER;
    send_msg(server_socket, &m);
}

void c_clear_finished()
{
    struct msg m;

    m.type = CLEAR_FINISHED;
    send_msg(server_socket, &m);
}

static char * get_output_file(int *pid)
{
    struct msg m;
    int res;
    char *string = 0;

    /* Send the request */
    m.type = ASK_OUTPUT;
    m.u.jobid = command_line.jobid;
    send_msg(server_socket, &m);

    /* Receive the answer */
    res = recv_msg(server_socket, &m);
    if(res != sizeof(m))
        error("Error in get_output_file");
    switch(m.type)
    {
    case ANSWER_OUTPUT:
        if (m.u.output.store_output)
        {
            /* Receive the output file name */
            string = (char *) malloc(m.u.output.ofilename_size);
            recv_bytes(server_socket, string, m.u.output.ofilename_size);
            *pid = m.u.output.pid;
            return string;
        }
        *pid = m.u.output.pid;
        return 0;
        /* WILL NOT GO FURTHER */
    case LIST_LINE: /* Only ONE line accepted */
        string = (char *) malloc(m.u.line_size);
        res = recv_bytes(server_socket, string, m.u.line_size);
        if(res != m.u.line_size)
            error("Error in get_output_file line size");
        fprintf(stderr, "Error in the request: %s", 
                string);
        exit(-1);
        /* WILL NOT GO FURTHER */
    default:
        warning("Wrong internal message in get_output_file line size");
    }
    /* This will never be reached */
    return 0;
}

void c_tail()
{
    char *str;
    int pid;
    str = get_output_file(&pid);
    if (str == 0)
    {
        fprintf(stderr, "The output is not stored. Cannot tail.\n");
        exit(-1);
    }
    c_run_tail(str);
}

void c_cat()
{
    char *str;
    int pid;
    str = get_output_file(&pid);
    if (str == 0)
    {
        fprintf(stderr, "The output is not stored. Cannot tail.\n");
        exit(-1);
    }
    c_run_cat(str);
}

void c_show_output_file()
{
    char *str;
    int pid;
    /* This will exit if there is any error */
    str = get_output_file(&pid);
    if (str == 0)
    {
        fprintf(stderr, "The output is not stored. Cannot tail.\n");
        exit(-1);
    }
    printf("%s\n", str);
    free(str);
}

void c_show_pid()
{
    char *str;
    int pid;
    /* This will exit if there is any error */
    str = get_output_file(&pid);
    printf("%i\n", pid);
}

void c_remove_job()
{
    struct msg m;
    int res;
    char *string = 0;

    /* Send the request */
    m.type = REMOVEJOB;
    m.u.jobid = command_line.jobid;
    send_msg(server_socket, &m);

    /* Receive the answer */
    res = recv_msg(server_socket, &m);
    if(res != sizeof(m))
        error("Error in remove_job");
    switch(m.type)
    {
    case REMOVEJOB_OK:
        return;
        /* WILL NOT GO FURTHER */
    case LIST_LINE: /* Only ONE line accepted */
        string = (char *) malloc(m.u.line_size);
        res = recv_bytes(server_socket, string, m.u.line_size);
        if(res != sizeof(m))
            error("Error in remove_job");
        fprintf(stderr, "Error in the request: %s", 
                string);
        exit(-1);
        /* WILL NOT GO FURTHER */
    default:
        warning("Wrong internal message in remove_job");
    }
    /* This will never be reached */
}

/* Returns the errorlevel */
int c_wait_job()
{
    struct msg m;
    int res;
    char *string = 0;

    /* Send the request */
    m.type = WAITJOB;
    m.u.jobid = command_line.jobid;
    send_msg(server_socket, &m);

    /* Receive the answer */
    res = recv_msg(server_socket, &m);
    if(res != sizeof(m))
        error("Error in wait_job");
    switch(m.type)
    {
    case WAITJOB_OK:
        return m.u.result.errorlevel;
        /* WILL NOT GO FURTHER */
    case LIST_LINE: /* Only ONE line accepted */
        string = (char *) malloc(m.u.line_size);
        res = recv_bytes(server_socket, string, m.u.line_size);
        if(res != m.u.line_size)
            error("Error in wait_job - line size");
        fprintf(stderr, "Error in the request: %s", 
                string);
        exit(-1);
        /* WILL NOT GO FURTHER */
    default:
        warning("Wrong internal message in c_wait_job");
    }
    /* This will never be reached */
    return -1;
}

void c_move_urgent()
{
    struct msg m;
    int res;
    char *string = 0;

    /* Send the request */
    m.type = URGENT;
    m.u.jobid = command_line.jobid;
    send_msg(server_socket, &m);

    /* Receive the answer */
    res = recv_msg(server_socket, &m);
    if(res != sizeof(m))
        error("Error in move_urgent");
    switch(m.type)
    {
    case URGENT_OK:
        return;
        /* WILL NOT GO FURTHER */
    case LIST_LINE: /* Only ONE line accepted */
        string = (char *) malloc(m.u.line_size);
        res = recv_bytes(server_socket, string, m.u.line_size);
        if(res != m.u.line_size)
            error("Error in move_urgent - line size");
        fprintf(stderr, "Error in the request: %s", 
                string);
        exit(-1);
        /* WILL NOT GO FURTHER */
    default:
        warning("Wrong internal message in move_urgent");
    }
    /* This will never be reached */
    return;
}

void c_get_state()
{
    struct msg m;
    int res;
    char *string = 0;

    /* Send the request */
    m.type = GET_STATE;
    m.u.jobid = command_line.jobid;
    send_msg(server_socket, &m);

    /* Receive the answer */
    res = recv_msg(server_socket, &m);
    if(res != sizeof(m))
        error("Error in get_state - line size");
    switch(m.type)
    {
    case ANSWER_STATE:
        printf("%s\n", jstate2string(m.u.state));
        return;
        /* WILL NOT GO FURTHER */
    case LIST_LINE: /* Only ONE line accepted */
        string = (char *) malloc(m.u.line_size);
        res = recv_bytes(server_socket, string, m.u.line_size);
        if(res != m.u.line_size)
            error("Error in get_state - line size");
        fprintf(stderr, "Error in the request: %s", 
                string);
        exit(-1);
        /* WILL NOT GO FURTHER */
    default:
        warning("Wrong internal message in get_state");
    }
    /* This will never be reached */
    return;
}

void c_swap_jobs()
{
    struct msg m;
    int res;
    char *string = 0;

    /* Send the request */
    m.type = SWAP_JOBS;
    m.u.swap.jobid1 = command_line.jobid;
    m.u.swap.jobid2 = command_line.jobid2;
    send_msg(server_socket, &m);

    /* Receive the answer */
    res = recv_msg(server_socket, &m);
    if(res != sizeof(m))
        error("Error in swap_jobs");
    switch(m.type)
    {
    case SWAP_JOBS_OK:
        return;
        /* WILL NOT GO FURTHER */
    case LIST_LINE: /* Only ONE line accepted */
        string = (char *) malloc(m.u.line_size);
        res = recv_bytes(server_socket, string, m.u.line_size);
        if(res != m.u.line_size)
            error("Error in swap_jobs - line size");
        fprintf(stderr, "Error in the request: %s", 
                string);
        exit(-1);
        /* WILL NOT GO FURTHER */
    default:
        warning("Wrong internal message in swap_jobs");
    }
    /* This will never be reached */
    return;
}