|
- #include <stdarg.h>
-
- #include "btcli.h"
-
- const char *btpd_dir;
- struct ipc *ipc;
-
- void
- diemsg(const char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- exit(1);
- }
-
- void
- btpd_connect(void)
- {
- if ((errno = ipc_open(btpd_dir, &ipc)) != 0)
- diemsg("cannot open connection to btpd in %s (%s).\n", btpd_dir,
- strerror(errno));
- }
-
- enum ipc_err
- handle_ipc_res(enum ipc_err code, const char *cmd, const char *target)
- {
- switch (code) {
- case IPC_OK:
- break;
- case IPC_COMMERR:
- diemsg("error in communication with btpd.\n");
- default:
- fprintf(stderr, "btcli %s '%s': %s.\n", cmd, target,
- ipc_strerror(code));
- }
- return code;
- }
-
- void
- print_percent(long long part, long long whole)
- {
- printf("%5.1f%% ", floor(1000.0 * part / whole) / 10);
- }
-
- void
- print_rate(long long rate)
- {
- if (rate >= 999.995 * (1 << 10))
- printf("%6.2fMB/s ", (double)rate / (1 << 20));
- else
- printf("%6.2fkB/s ", (double)rate / (1 << 10));
- }
-
- void
- print_size(long long size)
- {
- if (size >= 999.995 * (1 << 20))
- printf("%6.2fG ", (double)size / (1 << 30));
- else
- printf("%6.2fM ", (double)size / (1 << 20));
- }
- void
- print_ratio(long long part, long long whole)
- {
- printf("%7.2f ", (double)part / whole);
- }
-
- char
- tstate_char(enum ipc_tstate ts)
- {
- switch (ts) {
- case IPC_TSTATE_INACTIVE:
- return 'I';
- case IPC_TSTATE_START:
- return '+';
- case IPC_TSTATE_STOP:
- return '-';
- case IPC_TSTATE_LEECH:
- return 'L';
- case IPC_TSTATE_SEED:
- return 'S';
- }
- diemsg("unrecognized torrent state.\n");
- }
-
- int
- torrent_spec(char *arg, struct ipc_torrent *tp)
- {
- char *p;
- tp->u.num = strtoul(arg, &p, 10);
- if (*p == '\0') {
- tp->by_hash = 0;
- return 1;
- }
- if ((p = mi_load(arg, NULL)) == NULL) {
- fprintf(stderr, "btcli: bad torrent '%s' (%s).\n", arg,
- strerror(errno));
- return 0;
- }
- tp->by_hash = 1;
- mi_info_hash(p, tp->u.hash);
- free(p);
- return 1;
- }
-
- static struct {
- const char *name;
- void (*fun)(int, char **);
- void (*help)(void);
- } cmd_table[] = {
- { "add", cmd_add, usage_add },
- { "del", cmd_del, usage_del },
- { "kill", cmd_kill, usage_kill },
- { "list", cmd_list, usage_list },
- { "start", cmd_start, usage_start },
- { "stop", cmd_stop, usage_stop },
- { "stat", cmd_stat, usage_stat }
- };
-
- int ncmds = sizeof(cmd_table) / sizeof(cmd_table[0]);
-
- static void
- usage(void)
- {
- printf(
- "btcli is the btpd command line interface.\n"
- "\n"
- "Usage: btcli [main options] command [command options]\n"
- "\n"
- "Main options:\n"
- "-d dir\n"
- "\tThe btpd directory.\n"
- "\n"
- "--help [command]\n"
- "\tShow this text or help for the specified command.\n"
- "\n"
- "Commands:\n"
- "add\t- Add torrents to btpd.\n"
- "del\t- Remove torrents from btpd.\n"
- "kill\t- Shut down btpd.\n"
- "list\t- List torrents.\n"
- "start\t- Activate torrents.\n"
- "stat\t- Display stats for active torrents.\n"
- "stop\t- Deactivate torrents.\n"
- "\n"
- "Note:\n"
- "Torrents can be specified either with its number or its file.\n"
- "\n"
- );
- exit(1);
- }
-
- static struct option base_opts [] = {
- { "help", no_argument, NULL, 'H' },
- {NULL, 0, NULL, 0}
- };
-
- int
- main(int argc, char **argv)
- {
- int ch, help = 0;
-
- if (argc < 2)
- usage();
-
- while ((ch = getopt_long(argc, argv, "+d:", base_opts, NULL)) != -1) {
- switch (ch) {
- case 'd':
- btpd_dir = optarg;
- break;
- case 'H':
- help = 1;
- break;
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc == 0)
- usage();
-
- if (btpd_dir == NULL)
- if ((btpd_dir = find_btpd_dir()) == NULL)
- diemsg("cannot find the btpd directory.\n");
-
- optind = 0;
- int found = 0;
- for (int i = 0; !found && i < ncmds; i++) {
- if (strcmp(argv[0], cmd_table[i].name) == 0) {
- found = 1;
- if (help)
- cmd_table[i].help();
- else
- cmd_table[i].fun(argc, argv);
- }
- }
-
- if (!found)
- usage();
-
- return 0;
- }
|