Commit | Line | Data |
---|---|---|
06570394 TB |
1 | /* Copyright (C) 2018 Thomas Balzer */ |
2 | ||
3 | /* This file is part of tomd. */ | |
4 | ||
5 | /* tomd is free software: you can redistribute it and/or modify */ | |
6 | /* it under the terms of the GNU General Public License as published by */ | |
7 | /* the Free Software Foundation, either version 3 of the License, or */ | |
8 | /* (at your option) any later version. */ | |
9 | ||
10 | /* tomd is distributed in the hope that it will be useful, */ | |
11 | /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ | |
12 | /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ | |
13 | /* GNU General Public License for more details. */ | |
14 | ||
15 | /* You should have received a copy of the GNU General Public License */ | |
16 | /* along with tomd. If not, see <http://www.gnu.org/licenses/>. */ | |
17 | ||
18 | #include <stdlib.h> | |
19 | #include <stdio.h> | |
20 | #include <sys/un.h> | |
21 | #include <sys/socket.h> | |
22 | #include <unistd.h> | |
23 | ||
4dafa6fe | 24 | #include "../../include/macros.h" |
7bd7fa83 | 25 | #include "../../include/manifest.h" |
4dafa6fe | 26 | |
06570394 TB |
27 | static int sfd; |
28 | ||
805d0ff4 TB |
29 | static void header(void) |
30 | { | |
31 | tomc_p("Tom's Client, Copyright (C) 2018 Thomas Balzer"); | |
32 | tomc_p("GPL v3 or later license."); | |
33 | } | |
34 | ||
06570394 TB |
35 | static void init(void) |
36 | { | |
37 | /* init socket connection */ | |
38 | sfd = | |
39 | socket(PF_LOCAL, | |
40 | SOCK_STREAM, | |
41 | 0); | |
42 | if(sfd < 0){ | |
43 | perror("socket"); | |
44 | exit(EXIT_FAILURE); | |
45 | } | |
46 | ||
47 | struct sockaddr_un addr; | |
48 | addr.sun_family = AF_LOCAL; | |
49 | sprintf(addr.sun_path, "/run/user/1000/tomd/socket"); | |
1110e851 | 50 | |
06570394 TB |
51 | if(connect(sfd, (struct sockaddr *) &addr, SUN_LEN(&addr)) != 0){ |
52 | perror("connect"); | |
53 | exit(EXIT_FAILURE); | |
54 | } | |
7bd7fa83 | 55 | setup_socket(sfd); |
06570394 TB |
56 | } |
57 | ||
805d0ff4 TB |
58 | static char *default_name = "no_name"; |
59 | static struct{ | |
60 | char status, stop, kill, start; | |
61 | char *name; | |
62 | } options; | |
63 | ||
64 | static void extract_options(int argc, char **argv) | |
65 | { | |
66 | /* -status <name> Get status - if we thought we ran it, current real status */ | |
67 | /* -stop <name> Run provided command to gently stop */ | |
68 | /* -kill <name> Aggressive killing of process (signal 15) */ | |
69 | /* -start <name> Run name */ | |
70 | if(argc == 1){ | |
71 | /* only tomc given */ | |
72 | tomc_p("no args given."); | |
73 | exit(EXIT_SUCCESS); | |
74 | } | |
75 | ||
76 | options.name = NULL; | |
1110e851 | 77 | |
805d0ff4 TB |
78 | for(int i = 1; |
79 | i < argc; | |
80 | i++){ | |
81 | char *arg = argv[i]; | |
82 | #define X(op) {if(strcmp("-" #op, arg) == 0){options.op = 1; continue;}} | |
83 | X(status); | |
84 | X(stop); | |
85 | X(kill); | |
86 | X(start); | |
87 | #undef X | |
88 | /* assume last non option was the name */ | |
89 | options.name = arg; | |
90 | } | |
91 | ||
92 | if(options.name == NULL){ | |
93 | options.name = default_name; | |
94 | } | |
95 | } | |
96 | ||
952aba97 | 97 | static void print_options(void) |
06570394 | 98 | { |
805d0ff4 TB |
99 | tomc_p("---------"); |
100 | tomc_p(" name: %s", options.name); | |
101 | tomc_p(" kill: %d", options.kill); | |
102 | tomc_p("status: %d", options.status); | |
103 | tomc_p(" stop: %d", options.stop); | |
104 | tomc_p(" start: %d", options.start); | |
105 | tomc_p("---------"); | |
06570394 TB |
106 | } |
107 | ||
952aba97 TB |
108 | static char write_buf[100]; |
109 | static char socket_buf[100]; | |
110 | ||
111 | #define SOCK_WRITE(X) { \ | |
112 | strcpy(write_buf, X); \ | |
113 | int write_len = strlen(write_buf); \ | |
114 | ssize_t wrote = \ | |
115 | write(sfd, write_buf, write_len); \ | |
7bd7fa83 | 116 | /* tomc_p("wrote '%s' (%d)", write_buf, write_len); */ \ |
952aba97 TB |
117 | if(wrote != write_len){ \ |
118 | perror("[tomc] write size mismatch"); \ | |
119 | exit(EXIT_FAILURE); \ | |
1110e851 TB |
120 | }} |
121 | ||
7bd7fa83 TB |
122 | int last_read_size = 0; |
123 | ||
124 | static void do_read(char *line) | |
125 | { | |
1110e851 | 126 | /* printf("got %s as input.\n", line); */ |
7bd7fa83 TB |
127 | strcpy(socket_buf, line); |
128 | /* printf("socket_buf: %s\n", socket_buf); */ | |
129 | } | |
81215080 TB |
130 | |
131 | #define SOCK_READ { \ | |
7bd7fa83 | 132 | socket_read(do_read); \ |
952aba97 | 133 | } |
7bd7fa83 TB |
134 | /* int size = read(sfd, socket_buf, 100); \ */ |
135 | /* if(size == 0) { \ */ | |
136 | /* tomc_p("didn't actually get anything."); \ */ | |
137 | /* socket_buf[0] = '\0'; \ */ | |
138 | /* }else{ \ */ | |
139 | /* tomc_p("__debug__:size=%d", size); \ */ | |
140 | /* } \ */ | |
141 | /* socket_buf[size] = '\0'; \ */ | |
142 | /* tomc_p("__debug__: '%s'", socket_buf);\ */ | |
143 | /* last_read_size = size;\ */ | |
144 | /* } */ | |
952aba97 TB |
145 | #define SOCK_READ_X(X){ \ |
146 | SOCK_READ; \ | |
147 | if(strcmp(socket_buf, X) != 0){ \ | |
148 | tomc_p("protocol error. instead of ACK we got '%s'", socket_buf); \ | |
149 | exit(EXIT_FAILURE); \ | |
150 | } \ | |
151 | } | |
152 | #define SOCK_ACK {SOCK_READ_X("ACK")}; | |
153 | #define SOCK_REQUEST(X) { \ | |
154 | SOCK_WRITE(X); \ | |
155 | SOCK_ACK; \ | |
156 | SOCK_WRITE(options.name); \ | |
157 | SOCK_ACK; \ | |
952aba97 | 158 | } |
1110e851 | 159 | |
952aba97 TB |
160 | static void write_client(void) |
161 | { | |
162 | SOCK_WRITE("client:tomc"); | |
163 | SOCK_ACK; | |
164 | } | |
165 | ||
952aba97 TB |
166 | static void write_requests(void) |
167 | { | |
168 | write_client(); | |
169 | ||
170 | /* go through options to figure out what we want to do */ | |
171 | if(options.kill){ | |
172 | SOCK_REQUEST("kill"); | |
173 | ||
174 | if(options.start == 1 || | |
175 | options.stop == 1){ | |
176 | tomc_p("can only kill and status at once."); | |
177 | } | |
178 | } else { | |
179 | if(options.start){ | |
180 | if(options.stop){ | |
181 | tomc_p("can't start and stop at once."); | |
182 | } | |
183 | SOCK_REQUEST("start"); | |
184 | } | |
185 | if(options.stop){ | |
186 | SOCK_REQUEST("stop"); | |
187 | } | |
188 | } | |
189 | ||
190 | if(options.status){ | |
191 | SOCK_REQUEST("status"); | |
192 | } | |
7bd7fa83 TB |
193 | |
194 | while(1){ | |
1110e851 | 195 | /* printf("looking for that last ack.\n"); */ |
7bd7fa83 TB |
196 | SOCK_READ; |
197 | if(strcmp(socket_buf, "ACK") == 0){ | |
1110e851 TB |
198 | /* tomc_p("got the ending ack."); */ |
199 | write(sfd, "ACK", sizeof "ACK"); | |
7bd7fa83 TB |
200 | break; |
201 | }else{ | |
1110e851 | 202 | /* printf("in else.\n"); */ |
7bd7fa83 TB |
203 | /* int len = strlen(socket_buf); */ |
204 | /* int total = len; */ | |
205 | /* if(last_read_size == 0){ */ | |
206 | /* continue; */ | |
207 | /* } */ | |
208 | tomc_p(socket_buf); | |
209 | /* while(total != last_read_size -1){ */ | |
210 | /* tomc_p("__debug__:total=%d, size=%d", total, last_read_size); */ | |
211 | /* char *ptr = socket_buf + total; */ | |
212 | /* tomc_p("'%s'", ptr); */ | |
213 | /* total += strlen(ptr); */ | |
214 | /* } */ | |
215 | } | |
216 | } | |
952aba97 TB |
217 | } |
218 | ||
06570394 TB |
219 | int main(int argc, char **argv) |
220 | { | |
221 | header(); | |
805d0ff4 TB |
222 | extract_options(argc, argv); |
223 | print_options(); | |
06570394 | 224 | init(); |
952aba97 | 225 | write_requests(); |
7bd7fa83 | 226 | |
1110e851 TB |
227 | /* tomc_p("dying of our own accord."); */ |
228 | ||
06570394 TB |
229 | return EXIT_SUCCESS; |
230 | } |