+ int index, length;
+ enum afm_launch_mode result;
+
+ assert(cread->index == 0);
+ assert(!strncmp(&cread->buffer[cread->index], "mode", 4));
+
+ /* get the next token: the mode string */
+ if (!next_token(cread)) {
+ ERROR("%s:%d: no mode value set", cread->filepath,
+ cread->lineno);
+ errno = EINVAL;
+ return invalid_launch_mode;
+ }
+
+ /* record index and length */
+ index = cread->index;
+ length = cread->length;
+
+ /* check no extra characters */
+ if (next_token(cread)) {
+ ERROR("%s:%d: extra characters found after mode %.*s",
+ cread->filepath, cread->lineno, length,
+ &cread->buffer[index]);
+ errno = EINVAL;
+ return invalid_launch_mode;
+ }
+
+ /* get the mode */
+ cread->buffer[index + length] = 0;
+ result = launch_mode_of_name(&cread->buffer[index]);
+ if (result == invalid_launch_mode) {
+ ERROR("%s:%d: invalid mode value %s",
+ cread->filepath, cread->lineno, &cread->buffer[index]);
+ errno = EINVAL;
+ }
+ return result;
+}
+
+/*
+ * free the memory used by 'types'
+ */
+static void free_type_list(struct type_list *types)
+{
+ while (types != NULL) {
+ struct type_list *next = types->next;
+ free(types);
+ types = next;
+ }
+}
+
+/*
+ * reads the configuration file handled by 'cread'
+ * and adds its contents to the launcher list
+ *
+ * returns 0 in case of success or -1 in case of error.
+ */
+static int read_launchers(struct confread *cread)
+{
+ int rc, has_readyfd;
+ struct type_list *types, *lt;
+ struct desc_launcher *desc;
+ enum afm_launch_mode mode;
+ const char **vector;