Initial commit.
[oweals/dinit.git] / dinit-start.cc
1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <sys/un.h>
4 // #include <netinet/in.h>
5 #include <cstdio>
6 #include <unistd.h>
7 #include <cstring>
8 #include <string>
9 #include <iostream>
10
11 // dinit-start:  utility to start a dinit service
12
13 // This utility communicates with the dinit daemon via a unix socket (/dev/initctl).
14
15 // TODO move these into a common include file:
16 constexpr static int DINIT_CP_STARTSERVICE = 0;
17 constexpr static int DINIT_CP_STOPSERVICE  = 1;
18
19
20 int main(int argc, char **argv)
21 {
22     using namespace std;
23     
24     bool show_help = argc < 2;
25     char *service_name = nullptr;
26         
27     for (int i = 1; i < argc; i++) {
28         if (argv[i][0] == '-') {
29             if (strcmp(argv[i], "--help") == 0) {
30                 show_help = true;
31                 break;
32             }
33             else {
34                 cerr << "Unrecognized command-line parameter: " << argv[i] << endl;
35                 return 1;
36             }
37         }
38         else {
39             // service name
40             service_name = argv[i];
41             // TODO support multiple services (or at least give error if multiple services
42             //     supplied)
43         }
44     }
45
46     if (show_help) {
47         cout << "dinit-start:   start a dinit service" << endl;
48         cout << "  --help           : show this help" << endl;
49         cout << "  <service-name>   : start the named service" << endl;
50         return 1;
51     }
52     
53     int socknum = socket(AF_UNIX, SOCK_STREAM, 0);
54     if (socknum == -1) {
55         perror("socket");
56         return 1;
57     }
58
59     const char *naddr = "/dev/dinitctl";
60     
61     struct sockaddr_un name;
62     name.sun_family = AF_UNIX;
63     // memset(name.sun_path, 0, sizeof(name.sun_path));
64     strcpy(name.sun_path /* + 1 */, naddr);
65     int sunlen = 2 + strlen(naddr); // family, (string), nul
66     
67     int connr = connect(socknum, (struct sockaddr *) &name, sunlen);
68     if (connr == -1) {
69         perror("connect");
70         return 1;
71     }
72     
73     // Build buffer;
74     uint16_t sname_len = strlen(service_name);
75     int bufsize = 3 + sname_len;
76     char * buf = new char[bufsize];
77     
78     buf[0] = DINIT_CP_STARTSERVICE;
79     memcpy(buf + 1, &sname_len, 2);
80     memcpy(buf + 3, service_name, sname_len);
81     
82     int r = write(socknum, buf, bufsize);
83     if (r == -1) {
84         perror("write");
85     }
86     
87     return 0;
88 }