aboutsummaryrefslogtreecommitdiffstats
path: root/src/runesc.c
blob: 04fc26b19cb1e9eda81a4c13ff61d361ccc6bd4d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>

#include "runes.h"
#include "socket.h"

static int runes_socket_open_client(char *name);

int main (int argc, char *argv[])
{
    char *name, *buf;
    int s, i;
    size_t len, offset;
    uint32_t argc32 = argc, argv_len;

    name = runes_get_socket_name();
    s = runes_socket_open_client(name);

    len = sizeof(argc32) + sizeof(argv_len);
    for (i = 0; i < argc; ++i) {
        len += strlen(argv[i]) + 1;
    }

    buf = malloc(len);
    ((uint32_t*)buf)[0] = htonl(argc32);
    offset = sizeof(argc32) + sizeof(argv_len);
    ((uint32_t*)buf)[1] = htonl(len - offset);

    for (i = 0; i < argc; ++i) {
        size_t arg_len = strlen(argv[i]) + 1;
        memcpy(buf + offset, argv[i], arg_len);
        offset += arg_len;
    }

    send(s, buf, offset, 0);
    free(buf);
    shutdown(s, SHUT_RDWR);
}

static int runes_socket_open_client(char *name)
{
    int s;
    struct sockaddr_un client;

    if (strlen(name) + 1 > MAX_SOCKET_PATH_LEN) {
        runes_die("socket path %s is too long\n", name);
    }

    s = socket(AF_UNIX, SOCK_STREAM, 0);
    if (s < 0) {
        runes_die("couldn't create socket: %s\n", strerror(errno));
    }

    client.sun_family = AF_UNIX;
    strcpy(client.sun_path, name);
    if (connect(s, (struct sockaddr*)(&client), sizeof(struct sockaddr_un))) {
        runes_die("couldn't connect to socket at %s: %s\n", name,
                  strerror(errno));
    }

    return s;
}