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