This repository has been archived by the owner on Jan 1, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
121 lines (97 loc) · 2.66 KB
/
main.c
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#define err_and_ret(ret, fmt, ...) \
do { \
int rerrno = ret; \
fprintf(stderr, fmt "\n", ##__VA_ARGS__); \
if (sockfd != -1); \
close(sockfd); \
exit(rerrno); \
} while(0)
#define argv_cur(...) \
({ char *__t = argv[0]; argv++; argc--; __t; })
#define argv_next(...) \
{ argv++; argc--; }
/* cmd.c */
extern int cmd_add_proc(int argc, char *argv[], char *payload);
extern int cmd_del_proc(int argc, char *argv[], char *payload);
struct _cmd {
char *cmd;
int len;
int (*handler)(int argc, char *argv[], char *payload);
} lmkd_cmd[] = {
{ "add", sizeof "add" - 1, cmd_add_proc },
{ "del", sizeof "del" - 1, cmd_del_proc },
};
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
static inline int
xclose(int fd)
{
#if 0
char drop[1];
shutdown(fd, SHUT_WR);
read(fd, drop, sizeof(drop));
#endif
close(fd);
return 0;
}
static inline int
set_linger(int fd)
{
struct linger so_linger;
so_linger.l_onoff = 1;
so_linger.l_linger = 10;
return setsockopt(fd,
SOL_SOCKET, SO_LINGER,
&so_linger, sizeof(struct linger));
}
int
main(int argc, char *argv[])
{
char *sckname;
char *cmd;
#define BUFSZ 1024
char payload[BUFSZ];
int i, nbytes = -1;
/* sock */
int sockfd = -1, ret;
struct sockaddr_un addr;
if (argc < 3)
err_and_ret(-1, "Usage: %s <sock path> <cmd> [opts...]", basename(argv[0]));
argv_next();
sckname = argv_cur();
cmd = argv_cur();
for (i = 0; i < ARRAY_SIZE(lmkd_cmd); i++)
if (!strncmp(cmd, lmkd_cmd[i].cmd, lmkd_cmd[i].len)) {
nbytes = lmkd_cmd[i].handler(argc, argv, payload);
break;
}
if (nbytes <= 0)
err_and_ret(nbytes, "error on lmkd_cmd (%s)", cmd);
/* open sock and send */
sockfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (sockfd < 0)
err_and_ret(errno, "error on socket()");
ret = set_linger(sockfd);
if (ret < 0)
err_and_ret(errno, "error on set_linger()");
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, sckname, sizeof(addr.sun_path) - 1);
ret = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0)
err_and_ret(errno, "error on connect() to %s", sckname);
ret = send(sockfd, payload, nbytes, 0);
if (ret < 0)
err_and_ret(errno, "error on write()");
/* done */
xclose(sockfd);
return 0;
}