Blame alsaucm/usecase.c

Packit Service a9274b
/*
Packit Service a9274b
 *  This library is free software; you can redistribute it and/or
Packit Service a9274b
 *  modify it under the terms of the GNU Lesser General Public
Packit Service a9274b
 *  License as published by the Free Software Foundation; either
Packit Service a9274b
 *  version 2 of the License, or (at your option) any later version.
Packit Service a9274b
 *
Packit Service a9274b
 *  This library is distributed in the hope that it will be useful,
Packit Service a9274b
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service a9274b
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service a9274b
 *  Lesser General Public License for more details.
Packit Service a9274b
 *
Packit Service a9274b
 *  You should have received a copy of the GNU General Public License
Packit Service a9274b
 *  along with this program; if not, write to the Free Software
Packit Service a9274b
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Packit Service a9274b
 *
Packit Service a9274b
 *  Support for the verb/device/modifier core logic and API, 
Packit Service a9274b
 *  command line tool and file parser was kindly sponsored by 
Packit Service a9274b
 *  Texas Instruments Inc.
Packit Service a9274b
 *  Support for multiple active modifiers and devices, 
Packit Service a9274b
 *  transition sequences, multiple client access and user defined use
Packit Service a9274b
 *  cases was kindly sponsored by Wolfson Microelectronics PLC.
Packit Service a9274b
 * 
Packit Service a9274b
 *  Copyright (C) 2008-2010 SlimLogic Ltd
Packit Service a9274b
 *  Copyright (C) 2010 Wolfson Microelectronics PLC
Packit Service a9274b
 *  Copyright (C) 2010 Texas Instruments Inc.
Packit Service a9274b
 *  Copyright (C) 2010 Red Hat Inc.
Packit Service a9274b
 *  Authors: Liam Girdwood <lrg@slimlogic.co.uk>
Packit Service a9274b
 *           Stefan Schmidt <stefan@slimlogic.co.uk>
Packit Service a9274b
 *           Justin Xu <justinx@slimlogic.co.uk>
Packit Service a9274b
 *           Jaroslav Kysela <perex@perex.cz>
Packit Service a9274b
 */
Packit Service a9274b
Packit Service a9274b
#include <stdio.h>
Packit Service a9274b
#include <string.h>
Packit Service a9274b
#include <stdlib.h>
Packit Service a9274b
#include <unistd.h>
Packit Service a9274b
#include <signal.h>
Packit Service a9274b
#include <getopt.h>
Packit Service a9274b
#include <alsa/asoundlib.h>
Packit Service a9274b
#include <alsa/use-case.h>
Packit Service a9274b
#include "usecase.h"
Packit Service a9274b
#include "aconfig.h"
Packit Service a9274b
#include "version.h"
Packit Service a9274b
Packit Service a9274b
#define MAX_BUF 256
Packit Service a9274b
Packit Service a9274b
enum uc_cmd {
Packit Service a9274b
	/* management */
Packit Service a9274b
	OM_UNKNOWN = 0,
Packit Service a9274b
	OM_OPEN,
Packit Service a9274b
	OM_RESET,
Packit Service a9274b
	OM_RELOAD,
Packit Service a9274b
	OM_LISTCARDS,
Packit Service a9274b
	OM_DUMP,
Packit Service a9274b
	OM_LIST2,
Packit Service a9274b
	OM_LIST1,
Packit Service a9274b
Packit Service a9274b
	/* set/get */
Packit Service a9274b
	OM_SET,
Packit Service a9274b
	OM_GET,
Packit Service a9274b
	OM_GETI,
Packit Service a9274b
Packit Service a9274b
	/* misc */
Packit Service a9274b
	OM_HELP,
Packit Service a9274b
	OM_QUIT,
Packit Service a9274b
};
Packit Service a9274b
Packit Service a9274b
struct cmd {
Packit Service a9274b
	int code;
Packit Service a9274b
	int args;
Packit Service a9274b
	unsigned int opencard:1;
Packit Service a9274b
	const char *id;
Packit Service a9274b
};
Packit Service a9274b
Packit Service a9274b
static struct cmd cmds[] = {
Packit Service a9274b
	{ OM_OPEN, 1, 0, "open" },
Packit Service a9274b
	{ OM_RESET, 0, 1, "reset" },
Packit Service a9274b
	{ OM_RELOAD, 0, 1, "reload" },
Packit Service a9274b
	{ OM_LISTCARDS, 0, 0, "listcards" },
Packit Service a9274b
	{ OM_DUMP, 1, 1, "dump" },
Packit Service a9274b
	{ OM_LIST1, 1, 1, "list1" },
Packit Service a9274b
	{ OM_LIST2, 1, 1, "list" },
Packit Service a9274b
	{ OM_SET, 2, 1, "set" },
Packit Service a9274b
	{ OM_GET, 1, 1, "get" },
Packit Service a9274b
	{ OM_GETI, 1, 1, "geti" },
Packit Service a9274b
	{ OM_DUMP, 1, 1, "dump" },
Packit Service a9274b
	{ OM_HELP, 0, 0, "help" },
Packit Service a9274b
	{ OM_QUIT, 0, 0, "quit" },
Packit Service a9274b
	{ OM_HELP, 0, 0, "h" },
Packit Service a9274b
	{ OM_HELP, 0, 0, "?" },
Packit Service a9274b
	{ OM_QUIT, 0, 0, "q" },
Packit Service a9274b
	{ OM_UNKNOWN, 0, 0, NULL }
Packit Service a9274b
};
Packit Service a9274b
Packit Service a9274b
static void dump_help(struct context *context)
Packit Service a9274b
{
Packit Service a9274b
	if (context->command)
Packit Service a9274b
		printf("Usage: %s <options> [command]\n", context->command);
Packit Service a9274b
	printf(
Packit Service a9274b
"\nAvailable options:\n"
Packit Service a9274b
"  -h,--help                  this help\n"
Packit Service a9274b
"  -c,--card NAME             open card NAME\n"
Packit Service a9274b
"  -i,--interactive           interactive mode\n"
Packit Service a9274b
"  -b,--batch FILE            batch mode (use '-' for the stdin input)\n"
Packit Service a9274b
"  -n,--no-open               do not open first card found\n"
Packit Service a9274b
"\nAvailable commands:\n"
Packit Service a9274b
"  open NAME                  open card NAME\n"
Packit Service a9274b
"  reset                      reset sound card to default state\n"
Packit Service a9274b
"  reload                     reload configuration\n"
Packit Service a9274b
"  listcards                  list available cards\n"
Packit Service a9274b
"  dump FORMAT                dump all config information (format: text,json)\n"
Packit Service a9274b
"  list IDENTIFIER            list command, for items with value + comment\n"
Packit Service a9274b
"  list1 IDENTIFIER           list command, for items without comments\n"
Packit Service a9274b
"  get IDENTIFIER             get string value\n"
Packit Service a9274b
"  geti IDENTIFIER            get integer value\n"
Packit Service a9274b
"  set IDENTIFIER VALUE       set string value\n"
Packit Service a9274b
"  h,help                     help\n"
Packit Service a9274b
"  q,quit                     quit\n"
Packit Service a9274b
);
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
static int parse_line(struct context *context, char *line)
Packit Service a9274b
{
Packit Service a9274b
	char *start, **nargv;
Packit Service a9274b
	int c;
Packit Service a9274b
Packit Service a9274b
	context->argc = 0;
Packit Service a9274b
	while (*line) {
Packit Service a9274b
		while (*line && (*line == ' ' || *line == '\t' ||
Packit Service a9274b
							*line == '\n'))
Packit Service a9274b
			line++;
Packit Service a9274b
		c = *line;
Packit Service a9274b
		if (c == '\0')
Packit Service a9274b
			return 0;
Packit Service a9274b
		if (c == '\"' || c == '\'') {
Packit Service a9274b
			start = ++line;
Packit Service a9274b
			while (*line && *line != c)
Packit Service a9274b
				line++;
Packit Service a9274b
			if (*line) {
Packit Service a9274b
				*line = '\0';
Packit Service a9274b
				line++;
Packit Service a9274b
			}
Packit Service a9274b
		} else {
Packit Service a9274b
			start = line;
Packit Service a9274b
			while (*line && *line != ' ' && *line != '\t' &&
Packit Service a9274b
			       *line != '\n')
Packit Service a9274b
				line++;
Packit Service a9274b
			if (*line) {
Packit Service a9274b
				*line = '\0';
Packit Service a9274b
				line++;
Packit Service a9274b
			}
Packit Service a9274b
		}
Packit Service a9274b
		if (start[0] == '\0' && context->argc == 0)
Packit Service a9274b
			return 0;
Packit Service a9274b
		if (context->argc + 1 >= context->arga) {
Packit Service a9274b
			context->arga += 4;
Packit Service a9274b
			nargv = realloc(context->argv,
Packit Service a9274b
					context->arga * sizeof(char *));
Packit Service a9274b
			if (nargv == NULL)
Packit Service a9274b
				return -ENOMEM;
Packit Service a9274b
			context->argv = nargv;
Packit Service a9274b
		}
Packit Service a9274b
		context->argv[context->argc++] = start;
Packit Service a9274b
	}
Packit Service a9274b
	return 0;
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
static void my_exit(struct context *context, int exitcode)
Packit Service a9274b
{
Packit Service a9274b
	if (context->uc_mgr)
Packit Service a9274b
		snd_use_case_mgr_close(context->uc_mgr);
Packit Service a9274b
	if (context->arga > 0)
Packit Service a9274b
		free(context->argv);
Packit Service a9274b
	if (context->card)
Packit Service a9274b
		free(context->card);
Packit Service a9274b
	if (context->batch)
Packit Service a9274b
		free(context->batch);
Packit Service a9274b
	free(context);
Packit Service a9274b
	snd_config_update_free_global();
Packit Service a9274b
	exit(exitcode);
Packit Service a9274b
}
Packit Service a9274b
static void do_initial_open(struct context *context)
Packit Service a9274b
{
Packit Service a9274b
	int card, err;
Packit Service a9274b
	char name[16];
Packit Service a9274b
Packit Service a9274b
	if (!context->no_open && context->card == NULL) {
Packit Service a9274b
		card = -1;
Packit Service a9274b
		err = snd_card_next(&card;;
Packit Service a9274b
		if (err < 0) {
Packit Service a9274b
			fprintf(stderr, "%s: no sound card found: %s\n",
Packit Service a9274b
					context->command, snd_strerror(err));
Packit Service a9274b
			my_exit(context, EXIT_FAILURE);
Packit Service a9274b
		}
Packit Service a9274b
		snprintf(name, sizeof(name), "hw:%d", card);
Packit Service a9274b
		context->card = strdup(name);
Packit Service a9274b
	}
Packit Service a9274b
Packit Service a9274b
	/* open library */
Packit Service a9274b
	if (!context->no_open) {
Packit Service a9274b
		err = snd_use_case_mgr_open(&context->uc_mgr,
Packit Service a9274b
					    context->card);
Packit Service a9274b
		if (err < 0) {
Packit Service a9274b
			fprintf(stderr,
Packit Service a9274b
				"%s: error failed to open sound card %s: %s\n",
Packit Service a9274b
				context->command, context->card, snd_strerror(err));
Packit Service a9274b
			my_exit(context, EXIT_FAILURE);
Packit Service a9274b
		}
Packit Service a9274b
	}
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
static int do_one(struct context *context, struct cmd *cmd, char **argv)
Packit Service a9274b
{
Packit Service a9274b
	const char **list, *str;
Packit Service a9274b
	long lval;
Packit Service a9274b
	int err, i, j, entries;
Packit Service a9274b
Packit Service a9274b
	if (cmd->opencard && context->uc_mgr == NULL) {
Packit Service a9274b
		if (!context->no_open) {
Packit Service a9274b
			do_initial_open(context);
Packit Service a9274b
			context->no_open = 1;
Packit Service a9274b
		} else {
Packit Service a9274b
			fprintf(stderr, "%s: command '%s' requires an open card\n",
Packit Service a9274b
					context->command, cmd->id);
Packit Service a9274b
			return 0;
Packit Service a9274b
		}
Packit Service a9274b
	}
Packit Service a9274b
	switch (cmd->code) {
Packit Service a9274b
	case OM_OPEN:
Packit Service a9274b
		if (context->uc_mgr)
Packit Service a9274b
			snd_use_case_mgr_close(context->uc_mgr);
Packit Service a9274b
		context->uc_mgr = NULL;
Packit Service a9274b
		free(context->card);
Packit Service a9274b
		context->card = strdup(argv[0]);
Packit Service a9274b
		err = snd_use_case_mgr_open(&context->uc_mgr, context->card);
Packit Service a9274b
		if (err < 0) {
Packit Service a9274b
			fprintf(stderr,
Packit Service a9274b
				"%s: error failed to open sound card %s: %s\n",
Packit Service a9274b
				context->command, context->card,
Packit Service a9274b
				snd_strerror(err));
Packit Service a9274b
			return err;
Packit Service a9274b
		}
Packit Service a9274b
		break;
Packit Service a9274b
	case OM_RESET:
Packit Service a9274b
		err = snd_use_case_mgr_reset(context->uc_mgr);
Packit Service a9274b
		if (err < 0) {
Packit Service a9274b
			fprintf(stderr,
Packit Service a9274b
				"%s: error failed to reset sound card %s: %s\n",
Packit Service a9274b
				context->command, context->card,
Packit Service a9274b
				snd_strerror(err));
Packit Service a9274b
			return err;
Packit Service a9274b
		}
Packit Service a9274b
		break;
Packit Service a9274b
	case OM_RELOAD:
Packit Service a9274b
		err = snd_use_case_mgr_reload(context->uc_mgr);
Packit Service a9274b
		if (err < 0) {
Packit Service a9274b
			fprintf(stderr,
Packit Service a9274b
				"%s: error failed to reload manager %s: %s\n",
Packit Service a9274b
				context->command, context->card,
Packit Service a9274b
				snd_strerror(err));
Packit Service a9274b
			return err;
Packit Service a9274b
		}
Packit Service a9274b
		break;
Packit Service a9274b
	case OM_LISTCARDS:
Packit Service a9274b
		err = snd_use_case_card_list(&list);
Packit Service a9274b
		if (err < 0) {
Packit Service a9274b
			fprintf(stderr,
Packit Service a9274b
				"%s: error failed to get card list: %s\n",
Packit Service a9274b
				context->command,
Packit Service a9274b
				snd_strerror(err));
Packit Service a9274b
			return err;
Packit Service a9274b
		}
Packit Service a9274b
		if (err == 0) {
Packit Service a9274b
			printf("  list is empty\n");
Packit Service a9274b
			return 0;
Packit Service a9274b
		}
Packit Service a9274b
		for (i = 0; i < err / 2; i++) {
Packit Service a9274b
			printf("  %i: %s\n", i, list[i*2]);
Packit Service a9274b
			if (list[i*2+1])
Packit Service a9274b
				printf("    %s\n", list[i*2+1]);
Packit Service a9274b
		}
Packit Service a9274b
		snd_use_case_free_list(list, err);
Packit Service a9274b
		break;
Packit Service a9274b
	case OM_DUMP:
Packit Service a9274b
		dump(context, argv[0]);
Packit Service a9274b
		break;
Packit Service a9274b
	case OM_LIST1:
Packit Service a9274b
	case OM_LIST2:
Packit Service a9274b
		switch (cmd->code) {
Packit Service a9274b
		case OM_LIST1:
Packit Service a9274b
		    entries = 1;
Packit Service a9274b
		    break;
Packit Service a9274b
		case OM_LIST2:
Packit Service a9274b
		    entries = 2;
Packit Service a9274b
		    break;
Packit Service a9274b
		}
Packit Service a9274b
Packit Service a9274b
		err = snd_use_case_get_list(context->uc_mgr,
Packit Service a9274b
					    argv[0],
Packit Service a9274b
					    &list);
Packit Service a9274b
		if (err < 0) {
Packit Service a9274b
			fprintf(stderr,
Packit Service a9274b
				"%s: error failed to get list %s: %s\n",
Packit Service a9274b
				context->command, argv[0],
Packit Service a9274b
				snd_strerror(err));
Packit Service a9274b
			return err;
Packit Service a9274b
		}
Packit Service a9274b
		if (err == 0) {
Packit Service a9274b
			printf("  list is empty\n");
Packit Service a9274b
			return 0;
Packit Service a9274b
		}
Packit Service a9274b
		for (i = 0; i < err / entries; i++) {
Packit Service a9274b
			printf("  %i: %s\n", i, list[i*entries]);
Packit Service a9274b
			for (j = 0; j < entries - 1; j++)
Packit Service a9274b
				if (list[i*entries+j+1])
Packit Service a9274b
					printf("    %s\n", list[i*entries+j+1]);
Packit Service a9274b
		}
Packit Service a9274b
		snd_use_case_free_list(list, err);
Packit Service a9274b
		break;
Packit Service a9274b
	case OM_SET:
Packit Service a9274b
		err = snd_use_case_set(context->uc_mgr, argv[0], argv[1]);
Packit Service a9274b
		if (err < 0) {
Packit Service a9274b
			fprintf(stderr,
Packit Service a9274b
				"%s: error failed to set %s=%s: %s\n",
Packit Service a9274b
				context->command, argv[0], argv[1],
Packit Service a9274b
				snd_strerror(err));
Packit Service a9274b
			return err;
Packit Service a9274b
		}
Packit Service a9274b
		break;
Packit Service a9274b
	case OM_GET:
Packit Service a9274b
		err = snd_use_case_get(context->uc_mgr, argv[0], &str);
Packit Service a9274b
		if (err < 0) {
Packit Service a9274b
			fprintf(stderr,
Packit Service a9274b
				"%s: error failed to get %s: %s\n",
Packit Service a9274b
				context->command, argv[0],
Packit Service a9274b
				snd_strerror(err));
Packit Service a9274b
			return err;
Packit Service a9274b
		}
Packit Service a9274b
		printf("  %s=%s\n", argv[0], str);
Packit Service a9274b
		free((void *)str);
Packit Service a9274b
		break;
Packit Service a9274b
	case OM_GETI:
Packit Service a9274b
		err = snd_use_case_geti(context->uc_mgr, argv[0], &lval);
Packit Service a9274b
		if (err < 0) {
Packit Service a9274b
			fprintf(stderr,
Packit Service a9274b
				"%s: error failed to get integer %s: %s\n",
Packit Service a9274b
				context->command, argv[0],
Packit Service a9274b
				snd_strerror(err));
Packit Service a9274b
			return lval;
Packit Service a9274b
		}
Packit Service a9274b
		printf("  %s=%li\n", argv[0], lval);
Packit Service a9274b
		break;
Packit Service a9274b
	case OM_QUIT:
Packit Service a9274b
		context->do_exit = 1;
Packit Service a9274b
		break;
Packit Service a9274b
	case OM_HELP:
Packit Service a9274b
		dump_help(context);
Packit Service a9274b
		break;
Packit Service a9274b
	default:
Packit Service a9274b
		fprintf(stderr, "%s: unimplemented command '%s'\n",
Packit Service a9274b
				context->command, cmd->id);
Packit Service a9274b
		return -EINVAL;
Packit Service a9274b
	}
Packit Service a9274b
	return 0;
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
static int do_commands(struct context *context)
Packit Service a9274b
{
Packit Service a9274b
	char *command, **argv;
Packit Service a9274b
	struct cmd *cmd;
Packit Service a9274b
	int i, acnt, err;
Packit Service a9274b
Packit Service a9274b
	for (i = 0; i < context->argc && !context->do_exit; i++) {
Packit Service a9274b
		command = context->argv[i];
Packit Service a9274b
		for (cmd = cmds; cmd->id != NULL; cmd++) {
Packit Service a9274b
			if (strcmp(cmd->id, command) == 0)
Packit Service a9274b
				break;
Packit Service a9274b
		}
Packit Service a9274b
		if (cmd->id == NULL) {
Packit Service a9274b
			fprintf(stderr, "%s: unknown command '%s'\n",
Packit Service a9274b
						context->command, command);
Packit Service a9274b
			return -EINVAL;
Packit Service a9274b
		}
Packit Service a9274b
		acnt = context->argc - (i + 1);
Packit Service a9274b
		if (acnt < cmd->args) {
Packit Service a9274b
			fprintf(stderr, "%s: expected %i arguments (got %i)\n",
Packit Service a9274b
					context->command, cmd->args, acnt);
Packit Service a9274b
			return -EINVAL;
Packit Service a9274b
		}
Packit Service a9274b
		argv = context->argv + i + 1;
Packit Service a9274b
		err = do_one(context, cmd, argv);
Packit Service a9274b
		if (err < 0)
Packit Service a9274b
			return err;
Packit Service a9274b
		i += cmd->args;
Packit Service a9274b
	}
Packit Service a9274b
	return 0;
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
enum {
Packit Service a9274b
	OPT_VERSION = 1,
Packit Service a9274b
};
Packit Service a9274b
Packit Service a9274b
int main(int argc, char *argv[])
Packit Service a9274b
{
Packit Service a9274b
	static const char short_options[] = "hb:c:in";
Packit Service a9274b
	static const struct option long_options[] = {
Packit Service a9274b
		{"help", 0, 0, 'h'},
Packit Service a9274b
		{"version", 0, 0, OPT_VERSION},
Packit Service a9274b
		{"card", 1, 0, 'c'},
Packit Service a9274b
		{"interactive", 0, 0, 'i'},
Packit Service a9274b
		{"batch", 1, 0, 'b'},
Packit Service a9274b
		{"no-open", 0, 0, 'n'},
Packit Service a9274b
		{0, 0, 0, 0}
Packit Service a9274b
	};
Packit Service a9274b
	struct context *context;
Packit Service a9274b
	const char *command = argv[0];
Packit Service a9274b
	int c, err, option_index;
Packit Service a9274b
	char cmd[MAX_BUF];
Packit Service a9274b
	FILE *in;
Packit Service a9274b
Packit Service a9274b
	context = calloc(1, sizeof(*context));
Packit Service a9274b
	if (context == NULL)
Packit Service a9274b
		return EXIT_FAILURE;
Packit Service a9274b
	context->command = command;
Packit Service a9274b
	while ((c = getopt_long(argc, argv, short_options,
Packit Service a9274b
				 long_options, &option_index)) != -1) {
Packit Service a9274b
		switch (c) {
Packit Service a9274b
		case 'h':
Packit Service a9274b
			dump_help(context);
Packit Service a9274b
			break;
Packit Service a9274b
		case OPT_VERSION:
Packit Service a9274b
			printf("%s: version " SND_UTIL_VERSION_STR "\n", command);
Packit Service a9274b
			break;
Packit Service a9274b
		case 'c':
Packit Service a9274b
			if (context->card)
Packit Service a9274b
				free(context->card);
Packit Service a9274b
			context->card = strdup(optarg);
Packit Service a9274b
			break;
Packit Service a9274b
		case 'i':
Packit Service a9274b
			context->interactive = 1;
Packit Service a9274b
			context->batch = NULL;
Packit Service a9274b
			break;
Packit Service a9274b
		case 'b':
Packit Service a9274b
			context->batch = strdup(optarg);
Packit Service a9274b
			context->interactive = 0;
Packit Service a9274b
			break;
Packit Service a9274b
		case 'n':
Packit Service a9274b
			context->no_open = 1;
Packit Service a9274b
			break;
Packit Service a9274b
		default:
Packit Service a9274b
			fprintf(stderr, "Try '%s --help' for more information.\n", command);
Packit Service a9274b
			my_exit(context, EXIT_FAILURE);
Packit Service a9274b
		}
Packit Service a9274b
	}
Packit Service a9274b
Packit Service a9274b
	/* parse and execute any command line commands */
Packit Service a9274b
	if (argc > optind) {
Packit Service a9274b
		context->argv = argv + optind;
Packit Service a9274b
		context->argc = argc - optind;
Packit Service a9274b
		err = do_commands(context);
Packit Service a9274b
		if (err < 0)
Packit Service a9274b
			my_exit(context, EXIT_FAILURE);
Packit Service a9274b
	}
Packit Service a9274b
Packit Service a9274b
	if (!context->interactive && !context->batch)
Packit Service a9274b
		my_exit(context, EXIT_SUCCESS);
Packit Service a9274b
Packit Service a9274b
	if (context->interactive) {
Packit Service a9274b
		printf("%s: Interacive mode - 'q' to quit\n", command);
Packit Service a9274b
		in = stdin;
Packit Service a9274b
	} else {
Packit Service a9274b
		if (strcmp(context->batch, "-") == 0) {
Packit Service a9274b
			in = stdin;
Packit Service a9274b
		} else {
Packit Service a9274b
			in = fopen(context->batch, "r");
Packit Service a9274b
			if (in == NULL) {
Packit Service a9274b
				fprintf(stderr, "%s: error failed to open file '%s': %s\n",
Packit Service a9274b
					command, context->batch, strerror(-errno));
Packit Service a9274b
				my_exit(context, EXIT_FAILURE);
Packit Service a9274b
			}
Packit Service a9274b
		}
Packit Service a9274b
	}
Packit Service a9274b
Packit Service a9274b
	/* run the interactive command parser and handler */
Packit Service a9274b
	while (!context->do_exit && !feof(in)) {
Packit Service a9274b
		if (context->interactive)
Packit Service a9274b
			printf("%s>> ", argv[0]);
Packit Service a9274b
		fflush(stdin);
Packit Service a9274b
		if (fgets(cmd, MAX_BUF, in) == NULL)
Packit Service a9274b
			break;
Packit Service a9274b
		err = parse_line(context, cmd);
Packit Service a9274b
		if (err < 0) {
Packit Service a9274b
			fprintf(stderr, "%s: unable to parse line\n",
Packit Service a9274b
				command);
Packit Service a9274b
			my_exit(context, EXIT_FAILURE);
Packit Service a9274b
		}
Packit Service a9274b
		err = do_commands(context);
Packit Service a9274b
		if (err < 0) {
Packit Service a9274b
			if (context->interactive)
Packit Service a9274b
				printf("^^^ error, try again\n");
Packit Service a9274b
			else
Packit Service a9274b
				my_exit(context, EXIT_FAILURE);
Packit Service a9274b
		}
Packit Service a9274b
	}
Packit Service a9274b
	
Packit Service a9274b
	if (in != stdin)
Packit Service a9274b
		fclose(in);
Packit Service a9274b
Packit Service a9274b
	my_exit(context, EXIT_SUCCESS);
Packit Service a9274b
	return EXIT_SUCCESS;
Packit Service a9274b
}