1+ /*
2+ Copyright 2026 Northern.tech AS
3+
4+ This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
5+
6+ This program is free software; you can redistribute it and/or modify it
7+ under the terms of the GNU General Public License as published by the
8+ Free Software Foundation; version 3.
9+
10+ This program 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 this program; if not, write to the Free Software
17+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18+
19+ To the extent this program is licensed as part of the Enterprise
20+ versions of CFEngine, the applicable Commercial Open Source License
21+ (COSL) may apply to this file if you as a licensee so wish it. See
22+ included file COSL.txt.
23+ */
24+
25+
26+ #include <platform.h>
27+ #include <extensions.h>
28+ #include <logging.h>
129#include <stdio.h>
30+ #include <stdlib.h>
31+ #include <writer.h>
32+ #include <config.h>
33+ #include <generic_agent.h>
34+ #include <man.h>
35+ #include <cleanup.h>
36+
37+ #define REACTOR_NOVA_LIBRARY_NAME "cfengine-reactor-nova.so"
238
3- int main ()
39+ typedef int (* ReactorNovaMainFn )(bool no_fork );
40+
41+ static const Component COMPONENT =
42+ {
43+ .name = "cf-reactor" ,
44+ .website = CF_WEBSITE ,
45+ .copyright = CF_COPYRIGHT
46+ };
47+
48+ static const char * const CF_REACTOR_SHORT_DESCRIPTION = "CFEngine event reaction daemon" ;
49+
50+ static const char * const CF_REACTOR_MANPAGE_LONG_DESCRIPTION =
51+ "cf-reactor is a daemon reacting on events, currently only NOTIFY events from PostgreSQL." ;
52+
53+ static const struct option OPTIONS [] =
54+ {
55+ {"debug" , no_argument , 0 , 'd' },
56+ {"no-fork" , no_argument , 0 , 'F' },
57+ {"log-level" , required_argument , 0 , 'g' },
58+ {"help" , no_argument , 0 , 'h' },
59+ {"inform" , no_argument , 0 , 'I' },
60+ {"timestamp" , no_argument , 0 , 'l' },
61+ {"verbose" , no_argument , 0 , 'v' },
62+ {"version" , no_argument , 0 , 'V' },
63+ {NULL , 0 , 0 , '\0' }
64+ };
65+
66+ static const char * const HINTS [] =
467{
5- printf ("Hello cf-reactor!\n" );
6- return 0 ;
7- }
68+ "Enable debugging output and run in foreground" ,
69+ "Run as a foreground process (do not fork)" ,
70+ "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'" ,
71+ "Print the help message" ,
72+ "Print basic information about actions being taken" ,
73+ "Log timestamps on each line of log output" ,
74+ "Output verbose information about the behaviour of the agent" ,
75+ "Output the version of the software" ,
76+ NULL
77+ };
78+
79+ int main (int argc , char * argv [])
80+ {
81+ bool no_fork = false;
82+
83+ extern char * optarg ;
84+ int longopt_idx ;
85+ int c ;
86+ while ((c = getopt_long (argc , argv , "dFg:hIlMvV" ,
87+ OPTIONS , & longopt_idx ))
88+ != -1 )
89+ {
90+ switch (c )
91+ {
92+ case 'd' :
93+ LogSetGlobalLevel (LOG_LEVEL_DEBUG );
94+ no_fork = true;
95+ break ;
96+
97+ case 'F' :
98+ no_fork = true;
99+ break ;
100+
101+ case 'g' :
102+ LogSetGlobalLevelArgOrExit (optarg );
103+ break ;
104+
105+ case 'h' :
106+ {
107+ Writer * w = FileWriter (stdout );
108+ WriterWriteHelp (w , & COMPONENT , OPTIONS , HINTS , NULL , false, true);
109+ FileWriterDetach (w );
110+ }
111+ DoCleanupAndExit (EXIT_SUCCESS );
112+
113+ case 'I' :
114+ LogSetGlobalLevel (LOG_LEVEL_INFO );
115+ break ;
116+
117+ case 'l' :
118+ LoggingEnableTimestamps (true);
119+ break ;
120+
121+ case 'M' :
122+ {
123+ Writer * out = FileWriter (stdout );
124+ ManPageWrite (out , "cf-reactor" , time (NULL ),
125+ CF_REACTOR_SHORT_DESCRIPTION ,
126+ CF_REACTOR_MANPAGE_LONG_DESCRIPTION ,
127+ OPTIONS , HINTS ,
128+ NULL , false,
129+ true);
130+ FileWriterDetach (out );
131+ DoCleanupAndExit (EXIT_SUCCESS );
132+ }
133+
134+ case 'v' :
135+ LogSetGlobalLevel (LOG_LEVEL_VERBOSE );
136+ no_fork = true;
137+ break ;
138+
139+ case 'V' :
140+ {
141+ Writer * w = FileWriter (stdout );
142+ GenericAgentWriteVersion (w );
143+ FileWriterDetach (w );
144+ }
145+ DoCleanupAndExit (EXIT_SUCCESS );
146+
147+ }
148+ }
149+
150+ void * handle = extension_library_open (REACTOR_NOVA_LIBRARY_NAME );
151+ if (!handle )
152+ {
153+ Log (LOG_LEVEL_INFO , "Nova extension library '%s' not loaded or not available." , REACTOR_NOVA_LIBRARY_NAME );
154+ Log (LOG_LEVEL_INFO , "Running open-source cf-reactor." );
155+ return 0 ;
156+ }
157+
158+ ReactorNovaMainFn ReactorNovaMain = (ReactorNovaMainFn ) shlib_load (handle , "ReactorNovaMain" );
159+ if (!ReactorNovaMain )
160+ {
161+ Log (LOG_LEVEL_ERR , "Failed to load ReactorNovaMain symbol from '%s'." , REACTOR_NOVA_LIBRARY_NAME );
162+ extension_library_close (handle );
163+ return 1 ;
164+ }
165+
166+
167+ return ReactorNovaMain (no_fork );
168+ }
0 commit comments