Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_server_fcgi_main.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Frame FCGI Server
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
9 
15 #include "afw.h"
19 
20 typedef struct self_args_s {
21  union {
22  afw_utf8_t conf_file;
23  const afw_utf8_z_t *conf_file_z;
24  };
25  union {
26  afw_utf8_t path;
27  const afw_utf8_z_t *path_z;
28  };
29  union {
30  afw_utf8_t type_in;
31  const afw_utf8_z_t *type_in_z;
32  };
33  const afw_content_type_t *content_type_in;
34 
35  const afw_utf8_t *in_content;
36 
37  afw_integer_t number_of_threads;
38  afw_boolean_t help_option;
39 
40 } self_args_t;
41 
42 
43 /* Print usage. */
44 static void print_usage(void)
45 {
46  fprintf(stderr,
47  "Usage: afw_server_fcgi_main [-f filename] [-p path] [-n threads] [-e extension] "
48  "[-t content-type] [--help] [--version]\n");
49 }
50 
51 
52 /* Process args. */
53 static int process_args(int argc, const char * const * argv, self_args_t *args, afw_xctx_t *xctx)
54 {
55  int i;
56  long int n;
57 
58  /* Clear args. */
59  memset(args, 0, sizeof(self_args_t));
60 
61  args->number_of_threads = 1;
62 
63  /* Loop though argv. */
64  for (i = 1; i < argc; i++) {
65  if (strcmp(argv[i], "-f") == 0) {
66  i++;
67  if (args->conf_file_z || i >= argc) {
68  print_usage();
69  goto error;
70  }
71  args->conf_file_z = argv[i];
72  }
73  else if (strcmp(argv[i], "-p") == 0) {
74  i++;
75  if (args->path_z || i >= argc) {
76  print_usage();
77  goto error;
78  }
80  args->path_z = argv[i];
81  }
82  else if (strcmp(argv[i], "-n") == 0) {
83  i++;
84  n = strtol(argv[i], NULL, 10);
85  if (n < 0 || n > 9999 || errno == ERANGE) {
86  print_usage();
87  goto error;
88  }
89  args->number_of_threads = n;
90  }
91  else if (strcmp(argv[i], "--help") == 0) {
92  i++;
93  print_usage();
94  args->help_option = true;
95  return EXIT_SUCCESS;
96  }
97  else if (strcmp(argv[i], "--version") == 0) {
98  i++;
99  fprintf(stderr,
100  AFW_SERVER_FCGI_VERSION_COMMAND_STRING "\n");
101  args->help_option = true;
102  return EXIT_SUCCESS;
103  }
104  else if (strcmp(argv[i], "-t") == 0) {
105  i++;
106  if (i >= argc) {
107  print_usage();
108  goto error;
109  }
110  args->type_in_z = argv[i];
111  }
112  else if (strcmp(argv[i], "-e") == 0) {
113  i++;
114  if (i >= argc) {
115  print_usage();
116  goto error;
117  }
119  afw_utf8_create(argv[i], AFW_UTF8_Z_LEN, xctx->p, xctx),
120  NULL, NULL, xctx);
121  }
122  else {
123  print_usage();
124  goto error;
125  }
126  }
127 
128  /* If config file was not specified, set it to a default. */
129  if (!args->conf_file_z) {
130  args->conf_file_z = "afw.conf";
131  }
132 
133  /* If content-type was not specified, set it to a default. */
134  if (!args->type_in_z) {
135  args->type_in_z = "json";
136  }
137  args->type_in.len = strlen(args->type_in_z);
138 
139  /* If path was not specified, set it to a default. */
140  if (!args->path_z) {
141  args->path_z = ":9345";
142  }
143 
144  /* Set string lengths. */
145  args->conf_file.len = strlen(args->conf_file_z);
146  args->path.len = strlen(args->path_z);
147 
148  /* Normal return. */
149  return EXIT_SUCCESS;
150 
151  /* Error return. */
152 error:
153  return EXIT_FAILURE;
154 
155 }
156 
157 /* Main for afw_server_fcgi. */
158 int main(int argc, const char * const * argv) {
159  const afw_server_t *server;
160  const afw_error_t *create_error;
161  const afw_request_handler_t *director;
162  afw_xctx_t *xctx;
163  self_args_t args;
164  int rv;
165  const afw_value_t *conf;
166  const afw_memory_t *conf_file;
167 
168  /* Create Adaptive Framework environment for server. */
169  AFW_ENVIRONMENT_CREATE(xctx, argc, argv, &create_error);
170  if (!xctx) {
171  afw_error_print(xctx->env->stderr_fd, create_error);
172  return EXIT_FAILURE;
173  }
174 
175  /* Make sure environment is cleaned up. */
176  AFW_TRY {
177 
178  /* Register generated. */
180 
181  /* Process arguments. */
182  rv = process_args(argc, argv, &args, xctx);
183  if (args.help_option || rv != EXIT_SUCCESS) {
184  break;
185  }
186 
187  /* Configure environment. */
188  conf_file = afw_file_to_memory(&args.conf_file, 0, xctx->p, xctx);
189 
190  args.content_type_in = afw_environment_get_content_type(
191  &args.type_in, xctx);
192  if (!args.content_type_in) {
193  AFW_THROW_ERROR_Z(general, "Invalid content-type.", xctx);
194  }
195 
196  conf = afw_content_type_raw_to_value(args.content_type_in,
197  conf_file, &args.conf_file, xctx->p, xctx);
198  if (!afw_value_is_list(conf)) {
199  AFW_THROW_ERROR_Z(general, "Invalid configuration.", xctx);
200  }
202  ((const afw_value_list_t *)conf)->internal,
203  &args.conf_file, xctx);
204 
205  /* Create server. */
206  server = afw_server_fcgi_internal_create(args.path_z,
207  args.number_of_threads, xctx);
208 
209  /* Create director. */
210  director = afw_request_handler_director_create(server,
211  args.conf_file_z, xctx->p, xctx);
212 
213  /* Run server. */
214  afw_server_run(server, director, xctx);
215  }
216 
217  /* Print any unhandled errors. */
220  rv = EXIT_FAILURE;
221  }
222 
223  /* Make sure things are cleaned up. */
224  AFW_FINALLY{
226 
227  /* Special case: xctx is gone, so return before AFW_ENDTRY. */
228  return rv;
229  }
230 
231  AFW_ENDTRY;
232 }
Adaptive Framework Core API.
const afw_server_t * afw_server_fcgi_internal_create(const char *path, afw_integer_t thread_count, afw_xctx_t *xctx)
Create an FCGI afw_server.
void afw_server_fcgi_generated_register(afw_xctx_t *xctx)
Generated register for afw_server_fcgi.
Adaptive Framework register generated (afw_server_fcgi) header.
Internal header file for AFW FCGI Server.
Adaptive Framework Version (afw_server_fcgi_) header.
#define afw_value_is_list(A_VALUE)
Macro to determine if value is evaluated list.
#define AFW_UTF8_Z_LEN
String is NUL (0) terminate.
Definition: afw_common.h:266
_Bool afw_boolean_t
Definition: afw_common.h:373
afw_utf8_octet_t afw_utf8_z_t
NFC normalized UTF-8 null terminated string.
Definition: afw_common.h:523
apr_int64_t afw_integer_t
typedef for big signed int.
Definition: afw_common.h:321
#define afw_content_type_raw_to_value(instance, raw, source_location, p, xctx)
Call method raw_to_value of interface afw_content_type.
afw_environment_load_extension(const afw_utf8_t *extension_id, const afw_utf8_t *module_path, const afw_object_t *properties, afw_xctx_t *xctx)
Load and initialize environment extension.
#define AFW_ENVIRONMENT_CREATE(xctx, argc, argv, environment_create_error)
Call afw_environment_create() supplying version compiled with.
const afw_content_type_t * afw_environment_get_content_type(const afw_utf8_t *type, afw_xctx_t *xctx)
Get the afw_content_type struct associated with a content type.
afw_environment_release(afw_xctx_t *xctx)
Create the Adaptive Framework core environment and return base xctx.
void afw_environment_configure_with_object_list(const afw_list_t *entry_list, const afw_utf8_t *source_location, afw_xctx_t *xctx)
Configure environment with list of configuration entries.
#define AFW_FINALLY
Always executed regardless of error.
Definition: afw_error.h:702
#define AFW_CATCH_UNHANDLED
Catch an unhandled error that occurs in a AFW_TRY block.
Definition: afw_error.h:684
afw_error_print(FILE *fp, const afw_error_t *error)
Print error.
Definition: afw_error.c:679
#define AFW_ENDTRY
Ends an AFW try block.
Definition: afw_error.h:727
#define AFW_TRY
Begin an AFW TRY block.
Definition: afw_error.h:634
#define AFW_ERROR_THROWN
Access the thrown error. See AFW_TRY.
Definition: afw_error.h:554
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:283
afw_file_to_memory(const afw_utf8_t *file_path, apr_size_t file_size, const afw_pool_t *p, afw_xctx_t *xctx)
Read a file into a memory in a specifed pool.
Definition: afw_file.c:71
const afw_request_handler_t * afw_request_handler_director_create(const afw_server_t *server, const afw_utf8_z_t *config_file, const afw_pool_t *p, afw_xctx_t *xctx)
Create a request handler for director.
#define afw_server_run(instance, handler, xctx)
Call method run of interface afw_server.
#define afw_utf8_create(s, len, p, xctx)
Create utf-8 string without copy unless necessary in pool specified.
Definition: afw_utf8.h:239
Interface afw_content_type public struct.
FILE * stderr_fd
Open file descriptor used for writing error output. Default stderr.
Definition: afw_common.h:1425
Adaptive Framework Error.
Definition: afw_error.h:65
Struct for memory pointer and size.
Definition: afw_common.h:505
Interface afw_request_handler public struct.
Interface afw_server public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
struct for data type list values.
Interface afw_value public struct.
Interface afw_xctx public struct.