1 /*
2  * Copyright (C) 2018-2022 Intel Corporation.
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <malloc.h>
10 #include <fcntl.h>
11 #include <errno.h>
12 #include <getopt.h>
13 #include <string.h>
14 #include <limits.h>
15 #include "load_conf.h"
16 #include "fsutils.h"
17 #include "crash_reclassify.h"
18 #include "sender.h"
19 #include "event_queue.h"
20 #include "event_handler.h"
21 #include "channels.h"
22 #include "log_sys.h"
23 #include "version.h"
24 
25 #define CONFIG_INSTALL "/usr/share/defaults/telemetrics/acrnprobe.xml"
26 #define CONFIG_CUSTOMIZE "/etc/acrnprobe.xml"
27 
usage(void)28 void usage(void)
29 {
30 	printf("[Usage]\n");
31 	printf("\tacrnprobe -c [configuration file path] [-hV]\n");
32 	printf("[Options]\n");
33 	printf("\t-c,  --config         Configuration file\n");
34 	printf("\t-h,  --help           print the help message\n");
35 	printf("\t-V,  --version        Print the program version\n");
36 }
37 
uptime(const struct sender_t * sender)38 static void uptime(const struct sender_t *sender)
39 {
40 	int fd;
41 	int frequency;
42 	const struct uptime_t *uptime;
43 
44 	uptime = sender->uptime;
45 	if (!uptime)
46 		return;
47 
48 	if (cfg_atoi(uptime->frequency, uptime->frequency_len,
49 		     &frequency) == -1) {
50 		LOGE("Invalid frequency (%s) in config file, exiting...\n",
51 		     uptime->frequency);
52 		exit(-1);
53 	}
54 	if (frequency > 0)
55 		sleep(frequency);
56 
57 	fd = open(uptime->path, O_RDWR | O_CREAT, 0666);
58 	if (fd < 0)
59 		LOGE("open uptime_file with (%d, %s) failed, error (%s)\n",
60 				frequency, uptime->path, strerror(errno));
61 	else
62 		close(fd);
63 }
64 
main(int argc,char * argv[])65 int main(int argc, char *argv[])
66 {
67 	int ret;
68 	int id;
69 	int op;
70 	struct sender_t *sender;
71 	char cfg[PATH_MAX];
72 	const char * const config_path[2] = {
73 		CONFIG_CUSTOMIZE,
74 		CONFIG_INSTALL
75 	};
76 	const struct option opts[] = {
77 		{ "config", required_argument, NULL, 'c' },
78 		{ "help", no_argument, NULL, 'h' },
79 		{ "version", no_argument, NULL, 'V' },
80 		{ NULL, 0, NULL, 0 }
81 	};
82 
83 	cfg[0] = 0;
84 	while ((op = getopt_long(argc, argv, "c:hV", opts,
85 				 NULL)) != -1) {
86 		switch (op) {
87 		case 'c':
88 			strncpy(cfg, optarg, PATH_MAX - 1);
89 			break;
90 		case 'h':
91 			usage();
92 			return 0;
93 		case 'V':
94 			printf("version is %d.%d-%s, build by %s@%s\n",
95 				AP_MAJOR_VERSION, AP_MINOR_VERSION,
96 				AP_BUILD_VERSION, AP_BUILD_USER,
97 				AP_BUILD_TIME);
98 			return 0;
99 		case '?':
100 			usage();
101 			return -1;
102 		}
103 	}
104 
105 	if (!cfg[0]) {
106 		if (file_exists(config_path[0]))
107 			strncpy(cfg, config_path[0], PATH_MAX);
108 		else
109 			strncpy(cfg, config_path[1], PATH_MAX);
110 	}
111 	cfg[PATH_MAX - 1] = 0;
112 
113 	ret = load_conf(cfg);
114 	if (ret)
115 		return -1;
116 
117 	init_crash_reclassify();
118 	ret = init_sender();
119 	if (ret)
120 		return -1;
121 
122 	init_event_queue();
123 	ret = init_event_handler();
124 	if (ret)
125 		return -1;
126 
127 	ret = init_channels();
128 	if (ret)
129 		return -1;
130 
131 	while (1) {
132 		for_each_sender(id, sender, conf) {
133 			if (!sender)
134 				continue;
135 			uptime(sender);
136 		}
137 	}
138 	return 0;
139 }
140