1 /* PipeWire
2  *
3  * Copyright © 2018 Wim Taymans
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include <limits.h>
26 #include <signal.h>
27 #include <getopt.h>
28 #include <libgen.h>
29 
30 #include <spa/utils/result.h>
31 #include <pipewire/pipewire.h>
32 
33 #include <pipewire/i18n.h>
34 
35 #include "config.h"
36 
do_quit(void * data,int signal_number)37 static void do_quit(void *data, int signal_number)
38 {
39 	struct pw_main_loop *loop = data;
40 	pw_main_loop_quit(loop);
41 }
42 
show_help(const char * name,const char * config_name)43 static void show_help(const char *name, const char *config_name)
44 {
45 	fprintf(stdout, _("%s [options]\n"
46 		"  -h, --help                            Show this help\n"
47 		"      --version                         Show version\n"
48 		"  -c, --config                          Load config (Default %s)\n"),
49 		name,
50 		config_name);
51 }
52 
main(int argc,char * argv[])53 int main(int argc, char *argv[])
54 {
55 	struct pw_context *context = NULL;
56 	struct pw_main_loop *loop = NULL;
57 	struct pw_properties *properties = NULL;
58 	static const struct option long_options[] = {
59 		{ "help",	no_argument,		NULL, 'h' },
60 		{ "version",	no_argument,		NULL, 'V' },
61 		{ "config",	required_argument,	NULL, 'c' },
62 		{ "verbose",	no_argument,		NULL, 'v' },
63 
64 		{ NULL, 0, NULL, 0}
65 	};
66 	int c, res = 0;
67 	char path[PATH_MAX];
68 	const char *config_name;
69 	enum spa_log_level level = pw_log_level;
70 
71 	if (setenv("PIPEWIRE_INTERNAL", "1", 1) < 0)
72 		fprintf(stderr, "can't set PIPEWIRE_INTERNAL env: %m");
73 
74 	snprintf(path, sizeof(path), "%s.conf", argv[0]);
75 	config_name = basename(path);
76 
77 	pw_init(&argc, &argv);
78 
79 	while ((c = getopt_long(argc, argv, "hVc:v", long_options, NULL)) != -1) {
80 		switch (c) {
81 		case 'v':
82 			if (level < SPA_LOG_LEVEL_TRACE)
83 				pw_log_set_level(++level);
84 			break;
85 		case 'h':
86 			show_help(argv[0], config_name);
87 			return 0;
88 		case 'V':
89 			fprintf(stdout, "%s\n"
90 				"Compiled with libpipewire %s\n"
91 				"Linked with libpipewire %s\n",
92 				argv[0],
93 				pw_get_headers_version(),
94 				pw_get_library_version());
95 			return 0;
96 		case 'c':
97 			config_name = optarg;
98 			break;
99 		default:
100 			res = -EINVAL;
101 			goto done;
102 		}
103 	}
104 
105 	properties = pw_properties_new(
106 				PW_KEY_CONFIG_NAME, config_name,
107 				NULL);
108 
109 	loop = pw_main_loop_new(&properties->dict);
110 	if (loop == NULL) {
111 		pw_log_error("failed to create main-loop: %m");
112 		res = -errno;
113 		goto done;
114 	}
115 
116 	pw_loop_add_signal(pw_main_loop_get_loop(loop), SIGINT, do_quit, loop);
117 	pw_loop_add_signal(pw_main_loop_get_loop(loop), SIGTERM, do_quit, loop);
118 
119 	context = pw_context_new(pw_main_loop_get_loop(loop), properties, 0);
120 	properties = NULL;
121 
122 	if (context == NULL) {
123 		pw_log_error("failed to create context: %m");
124 		res = -errno;
125 		goto done;
126 	}
127 
128 	pw_log_info("start main loop");
129 	pw_main_loop_run(loop);
130 	pw_log_info("leave main loop");
131 
132 done:
133 	pw_properties_free(properties);
134 	if (context)
135 		pw_context_destroy(context);
136 	if (loop)
137 		pw_main_loop_destroy(loop);
138 	pw_deinit();
139 
140 	return res;
141 }
142