Ejemplo n.º 1
0
int VEObj::operateVE(const char * func, const char * action,
		const char ** options, int quiet)
{
	int rc, i;
	string_list argv;

	if (action && !quiet)
		logger(LOG_INFO, "%s CT %s ...", action, ctid());

	string_list_init(&argv);
	string_list_add(&argv, BIN_VZCTL);
	if (quiet)
		string_list_add(&argv, "--quiet");
	string_list_add(&argv, "--skiplock");
	string_list_add(&argv, "--skipowner");
	string_list_add(&argv, "--ignore-ha-cluster");
	string_list_add(&argv, (char *)func);
	string_list_add(&argv, ctid());
	if (options) {
		for (i = 0; options[i]; i++)
			string_list_add(&argv, (char *)options[i]);
	}

	rc = vzml_execve(&argv, NULL, -1, -1, quiet);

	string_list_clean(&argv);

	if (action && (rc == 0) && !quiet)
		logger(LOG_INFO, "done");

	return rc;
}
Ejemplo n.º 2
0
/* read network class id list */
static int read_idlist(struct string_list *idlist)
{
	int rc;
	char buf[BUFSIZ];
	const char *fname = "/etc/vz/conf/networks_classes";
	FILE *fd;
	char *p, *str;

	if ((fd = fopen(fname, "r")) == NULL)
		return putErr(MIG_ERR_SYSTEM, "fopen('%s') : %m", fname);

	while(fgets(buf, sizeof(buf), fd)) {
		/* remove leading spaces */
		p = buf;
		while (*p && isspace(*p))
			p++;
		str = p;
		/* skip comments */
	        if (*str == '#')
			continue;
		if ((p = strchr(str, ' ')) == NULL)
			continue;
		*p = '\0';
		if ((rc = string_list_add(idlist, str)))
			break;
	}
	fclose(fd);
	return rc;
}
Ejemplo n.º 3
0
/** @brief add item to list if it is not in it already
 * 
 * @return 0 if item already is in the list
 *         2 if item is not in the list but could
 *               not be added
 *         1 if item was not in the list and was successfully added
 */
int string_list_add_once(string_list** servers, char* string)
{
    if(string_list_contains(servers, string))
        return 0;
    if(string_list_add(servers, string))
        return 2;
    return 1;
}
Ejemplo n.º 4
0
/* copy all elements of <src> to <dst> */
int string_list_copy(struct string_list *dst, struct string_list *src)
{
	int rc;
	struct string_list_el *p;

	for (p = src->tqh_first; p != NULL; p = p->e.tqe_next)
		if ((rc = string_list_add(dst, p->s)))
			return rc;
	return 0;
}
Ejemplo n.º 5
0
static int init(int argc, char **argv, struct animation *banner)
{
	int i;
	struct string_list *filenames = NULL, *filenames_tail = NULL;
	int filenames_count = 0;

	init_log();

	i = get_options(argc, argv);
	if (i < 0)
		return usage(argv[0], NULL);

	for ( ; i < argc; ++i) {
		if (banner->interval == (unsigned int)-1)
			if (!parse_interval(argv[i], &banner->interval))
				continue;

		filenames_tail = string_list_add(&filenames, filenames_tail,
				argv[i]);
		if (!filenames_tail)
			return 1;
		else
			filenames_count++;
	}

	if (!filenames_count)
		return usage(argv[0], "No filenames specified");

	if (fb_init(&_Fb))
		return 1;
	if (init_proper_exit())
		return 1;
	if (animation_init(filenames, filenames_count, &_Fb, banner))
		return 1;
	string_list_destroy(filenames);

	if (banner->frame_count == 1 && RunCount == 1)
		banner->interval = 0; /* Single frame, exit after showing it */
	else if (banner->interval == (unsigned int)-1)
		banner->interval = 1000 / 24; /* 24fps */

	if (!Interactive && daemonify())
		ERR_RET(1, "could not create a daemon");

	return 0;
}
Ejemplo n.º 6
0
/* read interfaces list */
static int read_iflist(struct string_list *iflist)
{
	char buf[BUFSIZ];
	const char *cmd = "netstat -i";
	FILE *fd;
	int rc, status, retcode;
	char *p;
	const char *header = "Iface";

	logger(LOG_DEBUG, cmd);
	if ((fd = popen(cmd, "r")) == NULL)
		return putErr(MIG_ERR_SYSTEM, "popen('%s') : %m", cmd);

	/* skip header till 'Iface' */
	while(fgets(buf, sizeof(buf), fd)) {
		if (strncasecmp(header, buf, strlen(header)) == 0)
			break;
	}
	while(fgets(buf, sizeof(buf), fd)) {
		if ((p = strchr(buf, ' ')) == NULL)
			continue;
		*p = '\0';
		if ((rc = string_list_add(iflist, buf)))
			break;
	}
	status = pclose(fd);
	if (rc)
		return rc;
	if (WIFEXITED(status)) {
		if ((retcode = WEXITSTATUS(status))) {
			return putErr(MIG_ERR_SYSTEM,
				"'%s' return %d", cmd, retcode);
		}
	} else if (WIFSIGNALED(status)) {
		return putErr(MIG_ERR_SYSTEM,
			"'%s' got signal %d", cmd, WTERMSIG(status));
	} else {
		return putErr(MIG_ERR_SYSTEM,
			"'%s' exited with status %d", cmd, status);
	}

	return 0;
}
Ejemplo n.º 7
0
/* 0 - ipadd, 1 - ipdel*/
static int ipset(const char *ctid, const char *cmd, struct string_list *iplist)
{
	int rc;
	struct string_list argv;
	struct string_list_el *p;

	if (string_list_empty(iplist))
		return 0;

	string_list_init(&argv);

	string_list_add(&argv, BIN_VZCTL);
	string_list_add(&argv, "--skiplock");
	string_list_add(&argv, "--skipowner");
	string_list_add(&argv, "set");
	string_list_add(&argv, ctid);

	string_list_for_each(iplist, p) {
		string_list_add(&argv, cmd);
		string_list_add(&argv, p->s);
	}
Ejemplo n.º 8
0
/*
 * Internal function for `unzip_book'.
 * This is used to compress an EPWING book.
 */
static int
ebzip_unzip_book_epwing(EB_Book *book, const char *out_top_path,
    const char *book_path, EB_Subbook_Code *subbook_list, int subbook_count)
{
    EB_Subbook *subbook;
    EB_Error_Code error_code;
    EB_Font *font;
    String_List string_list;
    char in_path_name[PATH_MAX + 1];
    char out_sub_path[PATH_MAX + 1];
    char out_path_name[PATH_MAX + 1];
    char catalogs_file_name[EB_MAX_FILE_NAME_LENGTH];
    mode_t out_directory_mode;
    Zio_Code in_zio_code;
    int i, j;

    /*
     * If `out_top_path' and/or `book_path' represents "/", replace it
     * to an empty string.
     */
    if (strcmp(out_top_path, "/") == 0)
	out_top_path++;
    if (strcmp(book_path, "/") == 0)
	book_path++;

    /*
     * Initialize variables.
     */
    out_directory_mode = 0777 ^ get_umask();
    string_list_initialize(&string_list);

    error_code = eb_load_all_subbooks(book);
    if (error_code != EB_SUCCESS) {
	fprintf(stderr, "%s: %s\n", invoked_name,
	    eb_error_message(error_code));
    }

    /*
     * Uncompress a book.
     */
    for (i = 0; i < subbook_count; i++) {
	subbook = book->subbooks + subbook_list[i];

	/*
	 * Make an output directory for the current subbook.
	 */
	eb_compose_path_name(out_top_path, subbook->directory_name,
	    out_sub_path);
	if (!ebzip_test_flag
	    && make_missing_directory(out_sub_path, out_directory_mode) < 0) {
	    fprintf(stderr, _("%s: failed to create a directory, %s: %s\n"),
		invoked_name, strerror(errno), out_sub_path);
	    goto failed;
	}

	/*
	 * Make `data' sub directory for the current subbook.
	 */
	eb_compose_path_name2(out_top_path, subbook->directory_name,
	    subbook->data_directory_name, out_sub_path);
	if (!ebzip_test_flag
	    && make_missing_directory(out_sub_path, out_directory_mode) < 0) {
	    fprintf(stderr, _("%s: failed to create a directory, %s: %s\n"),
		invoked_name, strerror(errno), out_sub_path);
	    goto failed;
	}

	/*
	 * Uncompress HONMON/HONMON2 file.
	 */
	in_zio_code = zio_mode(&subbook->text_zio);
	eb_compose_path_name3(book->path, subbook->directory_name,
	    subbook->data_directory_name, subbook->text_file_name,
	    in_path_name);
	eb_compose_path_name3(out_top_path, subbook->directory_name,
	    subbook->data_directory_name, subbook->text_file_name,
	    out_path_name);

	if (in_zio_code != ZIO_INVALID
	    && !string_list_find(&string_list, in_path_name)) {
	    if (strncasecmp(subbook->text_file_name, "honmon2", 7) == 0)
		eb_fix_path_name_suffix(out_path_name, EBZIP_SUFFIX_ORG);
	    else
		eb_fix_path_name_suffix(out_path_name, EBZIP_SUFFIX_NONE);
	    if (ebzip_unzip_file(out_path_name, in_path_name, in_zio_code) < 0)
		goto failed;
	    string_list_add(&string_list, in_path_name);
	}

	/*
	 * Uncompress HONMONS file.
	 */
	in_zio_code = zio_mode(&subbook->sound_zio);
	eb_compose_path_name3(book->path, subbook->directory_name,
	    subbook->data_directory_name, subbook->sound_file_name,
	    in_path_name);
	eb_compose_path_name3(out_top_path, subbook->directory_name,
	    subbook->data_directory_name, subbook->sound_file_name,
	    out_path_name);
	eb_fix_path_name_suffix(out_path_name, EBZIP_SUFFIX_NONE);

	if (!ebzip_skip_flag_sound
	    && in_zio_code != ZIO_INVALID
	    && !string_list_find(&string_list, in_path_name)) {
	    if (ebzip_unzip_file(out_path_name, in_path_name, in_zio_code) < 0)
		goto failed;
	    string_list_add(&string_list, in_path_name);
	}

	/*
	 * Uncompress HONMONG file.
	 */
	in_zio_code = zio_mode(&subbook->graphic_zio);
	eb_compose_path_name3(book->path, subbook->directory_name,
	    subbook->data_directory_name, subbook->graphic_file_name,
	    in_path_name);
	eb_compose_path_name3(out_top_path, subbook->directory_name,
	    subbook->data_directory_name, subbook->graphic_file_name,
	    out_path_name);
	eb_fix_path_name_suffix(out_path_name, EBZIP_SUFFIX_NONE);

	if (!ebzip_skip_flag_graphic
	    && in_zio_code != ZIO_INVALID
	    && !string_list_find(&string_list, in_path_name)) {
	    if (ebzip_unzip_file(out_path_name, in_path_name, in_zio_code) < 0)
		goto failed;
	    string_list_add(&string_list, in_path_name);
	}

	/*
	 * Make `gaiji' sub directory for the current subbook.
	 */
	if (!ebzip_skip_flag_font) {
	    eb_compose_path_name2(out_top_path, subbook->directory_name,
		subbook->gaiji_directory_name, out_sub_path);
	    if (!ebzip_test_flag
		&& make_missing_directory(out_sub_path, out_directory_mode)
		< 0) {
		fprintf(stderr,
		    _("%s: failed to create a directory, %s: %s\n"),
		    invoked_name, strerror(errno), out_sub_path);
		goto failed;
	    }

	    /*
	     * Uncompress narrow font files.
	     */
	    for (j = 0; j < EB_MAX_FONTS; j++) {
		font = subbook->narrow_fonts + j;
		if (font->font_code == EB_FONT_INVALID)
		    continue;

		in_zio_code = zio_mode(&font->zio);
		eb_compose_path_name3(book->path, subbook->directory_name,
		    subbook->gaiji_directory_name, font->file_name,
		    in_path_name);
		eb_compose_path_name3(out_top_path, subbook->directory_name,
		    subbook->gaiji_directory_name, font->file_name,
		    out_path_name);
		eb_fix_path_name_suffix(out_path_name, EBZIP_SUFFIX_NONE);

		if (in_zio_code != ZIO_INVALID
		    && !string_list_find(&string_list, in_path_name)) {
		    if (ebzip_unzip_file(out_path_name, in_path_name,
			in_zio_code) < 0)
			goto failed;
		    string_list_add(&string_list, in_path_name);
		}
	    }

	    /*
	     * Uncompress wide font files.
	     */
	    for (j = 0; j < EB_MAX_FONTS; j++) {
		font = subbook->wide_fonts + j;
		if (font->font_code == EB_FONT_INVALID)
		    continue;

		in_zio_code = zio_mode(&font->zio);
		eb_compose_path_name3(book->path, subbook->directory_name,
		    subbook->gaiji_directory_name,
		    font->file_name, in_path_name);
		eb_compose_path_name3(out_top_path, subbook->directory_name,
		    subbook->gaiji_directory_name, font->file_name,
		    out_path_name);
		eb_fix_path_name_suffix(out_path_name, EBZIP_SUFFIX_NONE);

		if (in_zio_code != ZIO_INVALID
		    && !string_list_find(&string_list, in_path_name)) {
		    if (ebzip_unzip_file(out_path_name, in_path_name,
			in_zio_code) < 0)
			goto failed;
		    string_list_add(&string_list, in_path_name);
		}
	    }
	}

	/*
	 * Copy movie files.
	 */
	if (!ebzip_skip_flag_movie) {
	    eb_compose_path_name2(book->path, subbook->directory_name,
		subbook->movie_directory_name, in_path_name);
	    eb_compose_path_name2(out_top_path, subbook->directory_name,
		subbook->movie_directory_name, out_path_name);
	    if (ebzip_copy_files_in_directory(out_path_name, in_path_name) < 0)
		goto failed;
	}
    }

    /*
     * Copy CATALOGS file.
     */
    if (eb_find_file_name(book->path, "catalogs", catalogs_file_name)
	== EB_SUCCESS) {
	eb_compose_path_name(book->path, catalogs_file_name, in_path_name);
	eb_compose_path_name(out_top_path, catalogs_file_name, out_path_name);
	if (ebzip_copy_file(out_path_name, in_path_name) < 0)
	    goto failed;
    }

    string_list_finalize(&string_list);
    return 0;

    /*
     * An error occurs...
     */
  failed:
    string_list_finalize(&string_list);
    return -1;
}
Ejemplo n.º 9
0
/*
 * Internal function for `unzip_book'.
 * This is used to compress an EB book.
 */
static int
ebzip_unzip_book_eb(EB_Book *book, const char *out_top_path,
    const char *book_path, EB_Subbook_Code *subbook_list, int subbook_count)
{
    EB_Subbook *subbook;
    EB_Error_Code error_code;
    String_List string_list;
    char in_path_name[PATH_MAX + 1];
    char out_sub_path[PATH_MAX + 1];
    char out_path_name[PATH_MAX + 1];
    char catalog_file_name[EB_MAX_FILE_NAME_LENGTH];
    char language_file_name[EB_MAX_FILE_NAME_LENGTH];
    mode_t out_directory_mode;
    Zio_Code in_zio_code;
    int i;

    /*
     * If `out_top_path' and/or `book_path' represents "/", replace it
     * to an empty string.
     */
    if (strcmp(out_top_path, "/") == 0)
	out_top_path++;
    if (strcmp(book_path, "/") == 0)
	book_path++;

    /*
     * Initialize variables.
     */
    out_directory_mode = 0777 ^ get_umask();
    string_list_initialize(&string_list);

    error_code = eb_load_all_subbooks(book);
    if (error_code != EB_SUCCESS) {
	fprintf(stderr, "%s: %s\n", invoked_name,
	    eb_error_message(error_code));
    }

    /*
     * Uncompress a book.
     */
    for (i = 0; i < subbook_count; i++) {
	subbook = book->subbooks + subbook_list[i];

	/*
	 * Make an output directory for the current subbook.
	 */
	eb_compose_path_name(out_top_path, subbook->directory_name,
	    out_sub_path);
	if (!ebzip_test_flag
	    && make_missing_directory(out_sub_path, out_directory_mode) < 0) {
	    fprintf(stderr, _("%s: failed to create a directory, %s: %s\n"),
		invoked_name, strerror(errno), out_sub_path);
	    goto failed;
	}

	/*
	 * Uncompress START file.
	 */
	in_zio_code = zio_mode(&subbook->text_zio);
	eb_compose_path_name2(book->path, subbook->directory_name,
	    subbook->text_file_name, in_path_name);
	eb_compose_path_name2(out_top_path, subbook->directory_name,
	    subbook->text_file_name, out_path_name);
	eb_fix_path_name_suffix(out_path_name, EBZIP_SUFFIX_NONE);

	if (in_zio_code != ZIO_INVALID
	    && !string_list_find(&string_list, in_path_name)) {
	    if (ebzip_unzip_start_file(out_path_name, in_path_name,
		in_zio_code, subbook->index_page) < 0)
		goto failed;
	}

	if (!ebzip_test_flag
	    && rewrite_sebxa_start(out_path_name, subbook->index_page) < 0)
	    goto failed;
	string_list_add(&string_list, in_path_name);
    }

    /*
     * Uncompress a language file.
     */
    if (eb_find_file_name(book->path, "language", language_file_name)
	== EB_SUCCESS) {
	eb_compose_path_name(book->path, language_file_name, in_path_name);
	eb_compose_path_name(out_top_path, language_file_name, out_path_name);
	eb_path_name_zio_code(in_path_name, ZIO_PLAIN, &in_zio_code);
	eb_fix_path_name_suffix(out_path_name, EBZIP_SUFFIX_NONE);
	if (ebzip_unzip_file(out_path_name, in_path_name, in_zio_code) < 0)
	    goto failed;
    }

    /*
     * Copy CATALOG file.
     */
    if (eb_find_file_name(book->path, "catalog", catalog_file_name)
	== EB_SUCCESS) {
	eb_compose_path_name(book->path, catalog_file_name, in_path_name);
	eb_compose_path_name(out_top_path, catalog_file_name, out_path_name);
	if (ebzip_copy_file(out_path_name, in_path_name) < 0)
	    goto failed;
    }

    string_list_finalize(&string_list);
    return 0;

    /*
     * An error occurs...
     */
  failed:
    string_list_finalize(&string_list);
    return -1;
}
Ejemplo n.º 10
0
int main(int argc, char **argv)
{
	int rc = 0;
	SSL_METHOD *meth = NULL;
	SSL * ssl = NULL;
	SSL_CTX * ctx = NULL;
	X509 *server_cert = NULL;
	long res;
	char *srv;
	int sd, ferr;
	unsigned long addr;
	struct sockaddr_in saddr;
	unsigned short port = 4422;
	int lcipher;
	struct string_list arglist;
	char *dir, *name;
	char path[PATH_MAX+1];

	if ( argc < 3 )
		usage(basename(argv[0]), 1);
	if (parse_cmd_line(argc, argv))
		usage(basename(argv[0]), 1);

	if (argc <= optind+1)
		usage(basename(argv[0]), 1);
	srv = argv[optind];
	strncpy(path, argv[optind+1], sizeof(path));
	name = basename(path);
	dir = dirname(path);

	if ((addr = inet_addr(srv)) == INADDR_NONE) {
		/* need to resolve address */
		struct hostent *host;
		if ((host = gethostbyname(srv)) == NULL) {
			fprintf(stderr, "gethostbyname(%s) err : %m\n", srv);
			return 1;
		}
		memcpy(&addr, host->h_addr, sizeof(addr));
	}

	if (crtfile == NULL)
		crtfile = strdup("certificate.pem");
	if (keyfile == NULL)
		keyfile = strdup("private.key");
	if (ciphers == NULL)
		lcipher = 0;
	else if (strcasecmp(ciphers, "none") == 0)
		lcipher = 0;
	else
		lcipher = 1;

	string_list_init(&arglist);
	string_list_add(&arglist, "tar");
	string_list_add(&arglist, "-c");
	string_list_add(&arglist, "-S");
	string_list_add(&arglist, "--ignore-failed-read");
	string_list_add(&arglist, "-f");
	string_list_add(&arglist, "-");
	string_list_add(&arglist, "-C");
	string_list_add(&arglist, dir);
	string_list_add(&arglist, name);

	/* Set up the library */
	SSL_library_init();
	SSL_load_error_strings();

	/* Create SSL context (framework) */
	meth = SSLv23_client_method();
	if ((ctx = SSL_CTX_new(meth)) == NULL) {
		fprintf(stderr, "SSL_CTX_new() : %m\n");
		ERR_print_errors_fp(stderr);
		rc = 1;
		goto cleanup_0;
	}

	/* load certificat from file */
	if(SSL_CTX_use_certificate_file(ctx, crtfile, SSL_FILETYPE_PEM) < 1) {
		ERR_print_errors_fp(stderr);
		rc = 1;
		goto cleanup_1;
	}
	if(SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM) < 1) {
		ERR_print_errors_fp(stdout);
		rc = 1;
		goto cleanup_1;
	}
	if (lcipher) {
		/* load available cipher list */
		if (SSL_CTX_set_cipher_list(ctx, ciphers) == 0) {
			fprintf(stderr, "Error loading cipher list\n");
			ERR_print_errors_fp(stderr);
			rc = 1;
			goto cleanup_1;
		}
	}
	SSL_CTX_set_verify(ctx,
		SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);

	/* ----------------------------------------------- */
	/* Create a socket and connect to server using normal socket calls. */
	if ((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
		fprintf(stderr, "socket() err : %m\n");
		rc = 1;
		goto cleanup_1;
	}

	saddr.sin_family = AF_INET;
	saddr.sin_addr.s_addr = addr;
	saddr.sin_port = htons(port);

	if (connect(sd, (struct sockaddr *)&saddr, sizeof(saddr))) {
		// if (errno != EINPROGRESS) - for NONBLOCK
		fprintf(stderr, "connect() : %m\n");
		rc = 1;
		goto cleanup_1;
	}
	/* ----------------------------------------------- */
	/* Now we have TCP connection. Start SSL negotiation. */

	/* Create SSL obj */
	if ((ssl = SSL_new(ctx)) == NULL) {
		fprintf(stderr, "Error creating SSL object\n");
		ERR_print_errors_fp(stderr);
		rc = 1;
		goto cleanup_1;
	}

	SSL_set_fd(ssl, sd);
	SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

	/* try to connect */
	if(SSL_connect(ssl) <= 0) {
		fprintf(stderr, "Error attempting to connect\n");
		/* TODO SSL_get_error() */
		ERR_print_errors_fp(stderr);
		rc = 1;
		goto cleanup_2;
	}

	/* Get server's certificate. Note: dynamic allocation */
	if ((server_cert = SSL_get_peer_certificate(ssl)) == NULL) {
		fprintf(stderr, "Can't get peer certificate\n");
		ERR_print_errors_fp(stderr);
		rc = 1;
		goto cleanup_2;
	}

	X509_free(server_cert);

	/* verify the certificate
	From SSL_get_verify_result() man page:
	If no peer certificate was presented, the returned result code is
	X509_V_OK. This is because no verification error occurred, it does how-
	ever not indicate success. SSL_get_verify_result() is only useful in
	connection with SSL_get_peer_certificate(3).
	*/
	res = SSL_get_verify_result(ssl);
	/* will use expired certificate for test */
	if (	(res != X509_V_OK) &&
		(res != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) &&
		(res != X509_V_ERR_CERT_HAS_EXPIRED)) {
		fprintf(stderr, "Certificate verification error: %ld\n", res);
		fprintf(stderr, "See verify man page for more info\n");
		ERR_print_errors_fp(stderr);
		rc = 1;
		goto cleanup_2;
	}
	printf("Server certificate verified\n");

	ferr = dup(STDERR_FILENO);
	if (lcipher)
		;
	else {
		rc = run_rw(sd, sd, ferr, &arglist);
	}
	close(ferr);
	printf("rc = %d\n", rc);

	SSL_shutdown(ssl);

	/* Close the connection and free the context */
cleanup_2:
	if (ssl)
		SSL_free(ssl);

cleanup_1:
	if (ctx)
		SSL_CTX_free(ctx);

cleanup_0:
	string_list_clean(&arglist);

	return rc;
}
Ejemplo n.º 11
0
int
parse_list_main (int argc, char *argv[],
		 const ListDescriptionSet *list_sets, int num_sets,
		 const PredefinedCondition *conditions)
{
  int option;
  int result = 255;

  utils_remember_program_name (argv[0]);

  while ((option = getopt_long (argc, argv, "D:", parse_list_options, NULL))
	 != -1) {
    switch (option) {
    case OPTION_HELP:
      print_usage (stdout);
      printf ("%s", help_string);

      result = 0;
      goto exit_parse_list_main;

    case 'D':
      {
	const char *delimiter = strchr (optarg, '=');

	if (delimiter) {
	  if (memchr (optarg, '$', delimiter - optarg)) {
	    fprintf (stderr,
		     ("%s: fatal: "
		      "substitution name cannot contain dollar signs\n"),
		     short_program_name);
	    goto exit_parse_list_main;
	  }

	  string_list_add_from_buffer (&substitutions,
				       optarg, delimiter - optarg);
	  substitutions.last->association
	    = utils_duplicate_string (delimiter + 1);
	}
	else {
	  string_list_add (&substitutions, optarg);
	  substitutions.last->association = utils_duplicate_string ("");
	}
      }

      break;

    default:
      fprintf (stderr, "Try `%s --help' for more information.\n",
	       full_program_name);
      goto exit_parse_list_main;
    }
  }

  if (argc - optind == 3) {
    char *list_file_name = argv[optind];
    char *h_file_name	 = argv[optind + 1];
    char *c_file_name	 = argv[optind + 2];
    FILE *list_file	 = open_file (list_file_name, 0);

    if (list_file) {
      char *line;
      const ListDescription *lists = NULL;
      int k;

      string_list_prepend (&list_files, list_file_name);
      list_files.first->file = list_file;
      list_files.first->line_number = 0;

      do
	line = read_line ();
      while (line && (! *line || *line == '#'));

      if (looking_at ("@mode", &line)) {
	const char *mode = parse_thing (IDENTIFIER, &line, "mode name");

	if (mode) {
	  for (k = 0; k < num_sets; k++) {
	    if (strcmp (mode, list_sets[k].mode_name) == 0) {
	      lists = list_sets[k].lists;
	      break;
	    }
	  }

	  if (!lists)
	    print_error ("fatal: unknown mode `%s'", mode);
	}
      }
      else
	print_error ("fatal: `@mode' expected");

      if (lists) {
	FILE *h_file = open_file (h_file_name, 1);

	if (h_file) {
	  FILE *c_file = open_file (c_file_name, 1);

	  if (c_file) {
	    static const char *preamble =
	      "/* This file is automatically generated by `%s'.\n"
	      " * Do not modify it, edit `%s' instead.\n"
	      " */\n";

	    int n;
	    int h_file_name_length = strlen (h_file_name);

	    fprintf (h_file, preamble, short_program_name, list_file_name);
	    fprintf (c_file, preamble, short_program_name, list_file_name);

	    for (k = h_file_name_length; k >= 1; k--) {
	      if (h_file_name[k - 1] == DIRECTORY_SEPARATOR)
		break;
	    }

	    for (n = 0; k < h_file_name_length; k++) {
	      if (isalnum (h_file_name[k]))
		h_file_name[n++] = toupper (h_file_name[k]);
	      else if (h_file_name[k] == '.'
		       || h_file_name[k] == '_'
		       || h_file_name[k] == '-')
		h_file_name[n++] = '_';
	    }

	    h_file_name[n] = 0;
	    if (n > 4 && strcmp (h_file_name + n - 4, "_NEW") == 0)
	      h_file_name[n - 4] = 0;

	    fprintf (h_file, "\n\n#ifndef QUARRY_%s\n#define QUARRY_%s\n",
		     h_file_name, h_file_name);

	    predefined_conditions = conditions;
	    result = do_parse_lists (h_file, c_file, lists);

	    fprintf (h_file, "\n\n#endif /* QUARRY_%s */\n", h_file_name);

	    fclose (c_file);
	  }

	  fclose (h_file);
	}
      }

      string_list_empty (&list_files);

      while (condition_stack)
	pop_condition_stack ();
    }
  }
  else {
    print_usage (stderr);
    fprintf (stderr, "Try `%s --help' for more information.\n",
	     full_program_name);
  }

 exit_parse_list_main:
  string_list_empty (&substitutions);
  utils_free_program_name_strings ();

  return result;
}