1b975241f091e0d51c63d2e6eeb3306f0f1fd143
[tlb/tomd.git] / src / tomd / main.c
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 <stddef.h>
19 #include <stdio.h>
20 #include <errno.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <sys/un.h>
25 #include <sys/stat.h>
26 #include <sys/socket.h>
27
28 static void header(void)
29 {
30 printf("[tomd] Tom's Daemon, Copyright (C) 2018 Thomas Balzer\n");
31 printf("[tomd] GPL v3 or later license.\n");
32 }
33
34 static int sfd;
35 static char socket_dirname[100];
36 static char socket_filename[100];
37
38 static void gen_socket_filename(void)
39 {
40 uid_t this_user_id =
41 getuid();
42 sprintf(socket_dirname,
43 "/run/user/%d/tomd",
44 this_user_id);
45 sprintf(socket_filename,
46 "/run/user/%d/tomd/socket",
47 this_user_id);
48
49 printf("[tomd] making dir '%s'\n", socket_dirname);
50 /* lazy way */
51 char buf[100];
52 sprintf(buf, "mkdir -p %s", socket_dirname);
53 system(buf);
54 /* if(mkdir(socket_dirname, S_IRWXU) != 0){ */
55 /* perror("socket mkdir"); */
56 /* exit(EXIT_FAILURE); */
57 /* } */
58
59 printf("[tomd] removing file '%s'\n", socket_filename);
60 if(unlink(socket_filename) != 0){
61 if(errno == ENOENT){
62 printf("[tomd] socket file doesn't exist\n");
63 }else{
64 perror("[tomd] socket unlink");
65 exit(EXIT_FAILURE);
66 }
67 }
68 }
69
70 static void init(void)
71 {
72 gen_socket_filename();
73
74 /* listen on socket, respond to requests. */
75 /* perform all registered 'tick' operations */
76 sfd =
77 socket(PF_LOCAL, /* namespace - local unix socket */
78 SOCK_STREAM, /* style */
79 0); /* protocol */
80
81 if(sfd < 0){
82 perror("[tomd] socket");
83 exit(EXIT_FAILURE);
84 }
85
86 struct sockaddr_un name;
87 size_t size;
88
89 name.sun_family = AF_LOCAL;
90 strncpy(name.sun_path,
91 socket_filename,
92 sizeof(name.sun_path));
93
94 size = SUN_LEN(&name);
95 printf("[tomd] attempting to bind to '%s'\n",
96 socket_filename);
97 if(bind(sfd,
98 (struct sockaddr *) &name,
99 size) < 0){
100 perror("[tomd] bind");
101 exit(EXIT_FAILURE);
102 }
103
104 printf("[tomd] initialized tomd socket connections\n");
105 }
106
107 /* These defines are here to improve the local readability */
108 #define CHDIR 0
109 #define DONT_CHDIR 1
110 #define CLOSE_PIPES 0
111 #define DONT_CLOSE_PIPES 1
112
113 static void daemonize(void)
114 {
115 /* daemon is in unistd. */
116 /* arg1 - 0 changes dir to / */
117 /* arg2 - 0 closes all pipes (/dev/null) */
118 /* WARNING > THIS BEHAVIOR IS SILENT AND EASY TO MISPLACE THE
119 PROCESS */
120 daemon(DONT_CHDIR, DONT_CLOSE_PIPES);
121 }
122
123 static void run(void)
124 {
125 /* loop: */
126 /* 1 listen */
127 /* 2 accept/select */
128 /* 3 handle dgram */
129 int listen_bool =
130 listen(sfd,
131 10); /* max connection limit is 10 for arbitrary reasons */
132 if(listen_bool == -1){
133 perror("[tomd] listen");
134 exit(EXIT_FAILURE);
135 }
136
137 for(;;){
138 struct sockaddr addr;
139 socklen_t size;
140 int accept_sfd =
141 accept(sfd,
142 &addr, /* requester info */
143 &size); /* len of requester info */
144 if(accept_sfd < 0){
145 perror("[tomd] accept socket");
146 exit(EXIT_FAILURE);
147 }
148
149 /* int getsockname(accept_sfd, */
150 /* addr, */
151 /* size); */
152
153 printf("[tomd] accepted socket connection from '%s'\n",
154 ((struct sockaddr_un *) &addr)->sun_path);
155
156 char accept_buf[100] = {};
157
158 read(accept_sfd, accept_buf, 100);
159 printf("[tomd] got message '%s'\n, accept_buf");
160 close(accept_sfd);
161 }
162 }
163
164 static void cleanup(void)
165 {
166 if(sfd >= 0){
167 close(sfd);
168 }
169 }
170
171 int main(int argc, char **argv)
172 {
173 header();
174 init();
175 daemonize();
176 run();
177 cleanup();
178
179 return EXIT_SUCCESS;
180 }