blob: 0d52ecf49a9b905f95c6a8c5cad4c58008b2da84 [file] [log] [blame]
David Sodmanbbcb0522014-09-19 10:34:07 -07001/*
2 * Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
Dominik Behr2b9f1232016-08-02 01:11:12 -07007#include <errno.h>
David Sodman8ef20062015-01-06 09:23:40 -08008#include <fcntl.h>
9#include <limits.h>
10#include <pwd.h>
David Sodmanbbcb0522014-09-19 10:34:07 -070011#include <stdio.h>
12#include <stdlib.h>
David Sodmane46ea8a2015-03-13 15:47:12 -070013#include <string.h>
Daniel Nicoara76622c32015-03-18 17:47:54 -040014#include <sys/file.h>
David Sodmanef1ba362015-03-16 10:50:24 -070015#include <sys/stat.h>
David Sodman8ef20062015-01-06 09:23:40 -080016#include <unistd.h>
David Sodmanbbcb0522014-09-19 10:34:07 -070017
David Sodmane46ea8a2015-03-13 15:47:12 -070018#include "util.h"
19
Dominik Behr2b9f1232016-08-02 01:11:12 -070020static int openfd(char *path, int flags, int reqfd)
21{
22 int fd = open(path, flags);
23 if (fd < 0)
24 return -1;
25
26 if (fd == reqfd)
27 return reqfd;
28
29 if (dup2(fd, reqfd) >= 0) {
30 close(fd);
31 return reqfd;
32 }
33
34 close(fd);
35 return -1;
36}
37
38static int init_daemon_stdio(void)
39{
40 close(STDIN_FILENO);
41 close(STDOUT_FILENO);
42 close(STDERR_FILENO);
43
44 if (openfd("/dev/null", O_RDONLY, STDIN_FILENO) < 0)
45 return -1;
46
47 if (openfd("/dev/kmsg", O_WRONLY, STDOUT_FILENO) < 0)
48 return -1;
49
50 if (openfd("/dev/kmsg", O_WRONLY, STDERR_FILENO) < 0)
51 return -1;
52
53 return 0;
54}
55
David Sodmanbbcb0522014-09-19 10:34:07 -070056void daemonize()
57{
58 pid_t pid;
David Sodmanbbcb0522014-09-19 10:34:07 -070059
60 pid = fork();
61 if (pid == -1)
62 return;
63 else if (pid != 0)
64 exit(EXIT_SUCCESS);
65
66 if (setsid() == -1)
67 return;
68
Dominik Behr2b9f1232016-08-02 01:11:12 -070069 init_daemon_stdio();
70}
David Sodmanbbcb0522014-09-19 10:34:07 -070071
Dominik Behr2b9f1232016-08-02 01:11:12 -070072static int is_valid_fd(int fd)
73{
74 return fcntl(fd, F_GETFL) != -1 || errno != EBADF;
75}
David Sodmanbbcb0522014-09-19 10:34:07 -070076
Dominik Behr2b9f1232016-08-02 01:11:12 -070077void fix_stdio(void)
78{
79 if (!is_valid_fd(STDIN_FILENO)
80 || !is_valid_fd(STDOUT_FILENO)
81 || !is_valid_fd(STDERR_FILENO))
82 init_daemon_stdio();
David Sodmanbbcb0522014-09-19 10:34:07 -070083}
84
85#ifdef __clang__
86__attribute__((format (__printf__, 2, 0)))
87#endif
88void LOG(int severity, const char* fmt, ...)
89{
90 va_list arg_list;
Dominik Behrb1abcba2016-04-14 14:57:21 -070091 fprintf(stderr, "frecon(%d): ", getpid());
David Sodmanbbcb0522014-09-19 10:34:07 -070092 va_start( arg_list, fmt);
93 vfprintf(stderr, fmt, arg_list);
94 va_end(arg_list);
95 fprintf(stderr, "\n");
96}
David Sodman8ef20062015-01-06 09:23:40 -080097
Stéphane Marchesin00ff1872015-12-14 13:40:09 -080098void parse_location(char* loc_str, int* x, int* y)
David Sodman8ef20062015-01-06 09:23:40 -080099{
100 int count = 0;
101 char* savedptr;
David Sodman8ef20062015-01-06 09:23:40 -0800102 char* str;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800103 int* results[] = {x, y};
David Sodman8ef20062015-01-06 09:23:40 -0800104 long tmp;
105
Stéphane Marchesinac14d292015-12-14 15:27:18 -0800106 for (char* token = str = loc_str; token != NULL; str = NULL) {
David Sodman8ef20062015-01-06 09:23:40 -0800107 if (count > 1)
108 break;
109
110 token = strtok_r(str, ",", &savedptr);
111 if (token) {
112 tmp = MIN(INT_MAX, strtol(token, NULL, 0));
113 *(results[count++]) = (int)tmp;
114 }
115 }
116}
117
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800118void parse_filespec(char* filespec, char* filename,
Stéphane Marchesin8fc13522015-12-14 17:02:28 -0800119 int32_t* offset_x, int32_t* offset_y, uint32_t* duration,
120 uint32_t default_duration,
121 int32_t default_x, int32_t default_y)
David Sodman8ef20062015-01-06 09:23:40 -0800122{
123 char* saved_ptr;
124 char* token;
125
126 // defaults
127 *offset_x = default_x;
128 *offset_y = default_y;
129 *duration = default_duration;
130
131 token = filespec;
132 token = strtok_r(token, ":", &saved_ptr);
133 if (token)
134 strcpy(filename, token);
135
David Sodman8ef20062015-01-06 09:23:40 -0800136 token = strtok_r(NULL, ":", &saved_ptr);
137 if (token) {
138 *duration = strtoul(token, NULL, 0);
139 token = strtok_r(NULL, ",", &saved_ptr);
140 if (token) {
141 token = strtok_r(token, ",", &saved_ptr);
142 if (token) {
143 *offset_x = strtol(token, NULL, 0);
144 token = strtok_r(token, ",", &saved_ptr);
145 if (token)
146 *offset_y = strtol(token, NULL, 0);
147 }
148 }
149 }
150}
151
152void parse_image_option(char* optionstr, char** name, char** val)
153{
154 char** result[2] = { name, val };
155 int count = 0;
David Sodman8ef20062015-01-06 09:23:40 -0800156 char* str;
157 char* savedptr;
158
Stéphane Marchesinac14d292015-12-14 15:27:18 -0800159 for (char* token = str = optionstr; token != NULL; str = NULL) {
David Sodman8ef20062015-01-06 09:23:40 -0800160 if (count > 1)
161 break;
162
163 token = strtok_r(str, ":", &savedptr);
164 if (token) {
165 *(result[count]) = malloc(strlen(token) + 1);
166 strcpy(*(result[count]), token);
167 count++;
168 }
169 }
170}
171