mirror of
https://github.com/xorgy/mediafire-fuse
synced 2026-01-13 21:24:28 -08:00
mfshell: add configuration file parsing
This commit is contained in:
194
mfshell/main.c
194
mfshell/main.c
@@ -24,6 +24,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wordexp.h>
|
#include <wordexp.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "../utils/strings.h"
|
#include "../utils/strings.h"
|
||||||
#include "mfshell.h"
|
#include "mfshell.h"
|
||||||
@@ -32,6 +34,16 @@ static void mfshell_run(mfshell * shell);
|
|||||||
|
|
||||||
static void mfshell_parse_commands(mfshell * shell, char *command);
|
static void mfshell_parse_commands(mfshell * shell, char *command);
|
||||||
|
|
||||||
|
struct mfshell_user_options {
|
||||||
|
char *username;
|
||||||
|
char *password;
|
||||||
|
char *command;
|
||||||
|
char *server;
|
||||||
|
char *config;
|
||||||
|
} mfshell_user_options = {
|
||||||
|
NULL, NULL, NULL, NULL, NULL
|
||||||
|
};
|
||||||
|
|
||||||
void print_help(const char *cmd)
|
void print_help(const char *cmd)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "A shell to access a MediaFire account.\n");
|
fprintf(stderr, "A shell to access a MediaFire account.\n");
|
||||||
@@ -59,22 +71,39 @@ void print_help(const char *cmd)
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, " %s -c help\n", cmd);
|
fprintf(stderr, " %s -c help\n", cmd);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
"If arguments are given multiple times, the first one will be\n"
|
||||||
|
"used.\n");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
"Arguments given on the commandline will overwrite arguments\n"
|
||||||
|
"given in the configuration file\n");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
"The configuration file is parsed as if it was an argument\n"
|
||||||
|
"string except that linebreaks are allowed between arguments.\n"
|
||||||
|
"Lines starting with a # (hash) are ignored\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
parse_argv(int argc, char *const argv[], char **username,
|
parse_argv(int argc, char *const argv[])
|
||||||
char **password, char **server, char **command)
|
|
||||||
{
|
{
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"command", required_argument, 0, 'c'},
|
{"command", required_argument, 0, 'c'},
|
||||||
|
{"config", required_argument, 0, 'f'},
|
||||||
{"username", required_argument, 0, 'u'},
|
{"username", required_argument, 0, 'u'},
|
||||||
{"password", required_argument, 0, 'p'},
|
{"password", required_argument, 0, 'p'},
|
||||||
{"server", required_argument, 0, 's'},
|
{"server", required_argument, 0, 's'},
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
{"version", no_argument, 0, 'v'}
|
{"version", no_argument, 0, 'v'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
// resetting optind because we want to be able to call getopt_long
|
||||||
|
// multiple times for the commandline arguments as well as for the
|
||||||
|
// configuration file
|
||||||
|
optind = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
c = getopt_long(argc, argv, "c:u:p:s:hv", long_options, NULL);
|
c = getopt_long(argc, argv, "c:u:p:s:hv", long_options, NULL);
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
@@ -82,17 +111,24 @@ parse_argv(int argc, char *const argv[], char **username,
|
|||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
*command = strdup(optarg);
|
if (mfshell_user_options.command == NULL)
|
||||||
|
mfshell_user_options.command = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
*username = strdup(optarg);
|
if (mfshell_user_options.username == NULL)
|
||||||
|
mfshell_user_options.username = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
*password = strdup(optarg);
|
if (mfshell_user_options.password == NULL)
|
||||||
|
mfshell_user_options.password = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
*server = strdup(optarg);
|
if (mfshell_user_options.server == NULL)
|
||||||
|
mfshell_user_options.server = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
if (mfshell_user_options.config == NULL)
|
||||||
|
mfshell_user_options.config = strdup(optarg);
|
||||||
case 'h':
|
case 'h':
|
||||||
print_help(argv[0]);
|
print_help(argv[0]);
|
||||||
exit(0);
|
exit(0);
|
||||||
@@ -112,56 +148,158 @@ parse_argv(int argc, char *const argv[], char **username,
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*password != NULL && *username == NULL) {
|
if (mfshell_user_options.password != NULL &&
|
||||||
|
mfshell_user_options.username == NULL) {
|
||||||
fprintf(stderr, "You cannot pass the password without the username\n");
|
fprintf(stderr, "You cannot pass the password without the username\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void parse_config_file(FILE *fp)
|
||||||
|
{
|
||||||
|
// read the config file line by line and pass each line to wordexp to
|
||||||
|
// retain proper quoting
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
ssize_t read;
|
||||||
|
wordexp_t p;
|
||||||
|
int ret, i;
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
|
||||||
|
while ((read = getline(&line, &len, fp)) != -1) {
|
||||||
|
if (line[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// replace possible trailing newline by zero
|
||||||
|
if (line[strlen(line) - 1] == '\n')
|
||||||
|
line[strlen(line) - 1] = '\0';
|
||||||
|
ret = wordexp(line, &p, WRDE_SHOWERR | WRDE_UNDEF);
|
||||||
|
if (ret != 0) {
|
||||||
|
switch (ret) {
|
||||||
|
case WRDE_BADCHAR:
|
||||||
|
fprintf(stderr, "wordexp: WRDE_BADCHAR\n");
|
||||||
|
break;
|
||||||
|
case WRDE_BADVAL:
|
||||||
|
fprintf(stderr, "wordexp: WRDE_BADVAL\n");
|
||||||
|
break;
|
||||||
|
case WRDE_CMDSUB:
|
||||||
|
fprintf(stderr, "wordexp: WRDE_CMDSUB\n");
|
||||||
|
break;
|
||||||
|
case WRDE_NOSPACE:
|
||||||
|
fprintf(stderr, "wordexp: WRDE_NOSPACE\n");
|
||||||
|
break;
|
||||||
|
case WRDE_SYNTAX:
|
||||||
|
fprintf(stderr, "wordexp: WRDE_SYNTAX\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wordfree(&p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// prepend a dummy program name so that getopt_long will be able to
|
||||||
|
// parse it
|
||||||
|
argc = p.we_wordc + 1;
|
||||||
|
// allocate one more than argc for trailing NULL
|
||||||
|
argv = (char **)malloc(sizeof(char*)*(argc+1));
|
||||||
|
argv[0] = ""; // dummy program name
|
||||||
|
for (i = 1; i < argc; i++)
|
||||||
|
argv[i] = p.we_wordv[i-1];
|
||||||
|
argv[argc] = NULL;
|
||||||
|
parse_argv(argc, argv);
|
||||||
|
free(argv);
|
||||||
|
wordfree(&p);
|
||||||
|
}
|
||||||
|
free(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parse_config()
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *homedir;
|
||||||
|
// parse the configuration file
|
||||||
|
// if a value is not set (it is NULL) then it has not been set by the
|
||||||
|
// commandline and should be set by the configuration file
|
||||||
|
|
||||||
|
// try set config file first if set
|
||||||
|
if (mfshell_user_options.config != NULL &&
|
||||||
|
(fp = fopen(mfshell_user_options.config, "r")) != NULL) {
|
||||||
|
parse_config_file(fp);
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try "./.mediafire-tools.conf" second
|
||||||
|
if ((fp = fopen("./.mediafire-tools.conf", "r")) != NULL) {
|
||||||
|
parse_config_file(fp);
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try "~/.mediafire-tools.conf" third
|
||||||
|
if ((homedir = getenv("HOME")) == NULL) {
|
||||||
|
homedir = getpwuid(getuid())->pw_dir;
|
||||||
|
}
|
||||||
|
homedir = strdup_printf("%s/.mediafire-tools.conf", homedir);
|
||||||
|
if ((fp = fopen("./.mediafire-tools.conf", "r")) != NULL) {
|
||||||
|
parse_config_file(fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
free(homedir);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *const argv[])
|
int main(int argc, char *const argv[])
|
||||||
{
|
{
|
||||||
mfshell *shell;
|
mfshell *shell;
|
||||||
char *server = "www.mediafire.com";
|
|
||||||
char *username = NULL;
|
|
||||||
char *password = NULL;
|
|
||||||
char *command = NULL;
|
|
||||||
char *auth_cmd;
|
char *auth_cmd;
|
||||||
|
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
|
|
||||||
parse_argv(argc, argv, &username, &password, &server, &command);
|
parse_argv(argc, argv);
|
||||||
|
|
||||||
|
parse_config();
|
||||||
|
|
||||||
|
// if server was neither set on the commandline nor in the config, set it
|
||||||
|
// to the default value
|
||||||
|
if (mfshell_user_options.server == NULL) {
|
||||||
|
mfshell_user_options.server = strdup("www.mediafire.com");
|
||||||
|
}
|
||||||
|
|
||||||
shell = mfshell_create(35860, "2c6dq0gb2sr8rgsue5a347lzpjnaay46yjazjcjg",
|
shell = mfshell_create(35860, "2c6dq0gb2sr8rgsue5a347lzpjnaay46yjazjcjg",
|
||||||
server);
|
mfshell_user_options.server);
|
||||||
|
|
||||||
if (username != NULL) {
|
// if at least username was set, authenticate automatically
|
||||||
if (password != NULL) {
|
if (mfshell_user_options.username != NULL) {
|
||||||
auth_cmd = strdup_printf("auth %s %s", username, password);
|
if (mfshell_user_options.password != NULL) {
|
||||||
|
auth_cmd = strdup_printf("auth %s %s",
|
||||||
|
mfshell_user_options.username,
|
||||||
|
mfshell_user_options.password);
|
||||||
} else {
|
} else {
|
||||||
auth_cmd = strdup_printf("auth %s", username);
|
auth_cmd = strdup_printf("auth %s", mfshell_user_options.username);
|
||||||
}
|
}
|
||||||
mfshell_parse_commands(shell, auth_cmd);
|
mfshell_parse_commands(shell, auth_cmd);
|
||||||
free(auth_cmd);
|
free(auth_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == NULL) {
|
if (mfshell_user_options.command == NULL) {
|
||||||
// begin shell mode
|
// begin shell mode
|
||||||
mfshell_run(shell);
|
mfshell_run(shell);
|
||||||
} else {
|
} else {
|
||||||
// interpret command
|
// interpret command
|
||||||
mfshell_parse_commands(shell, command);
|
mfshell_parse_commands(shell, mfshell_user_options.command);
|
||||||
}
|
}
|
||||||
|
|
||||||
mfshell_destroy(shell);
|
mfshell_destroy(shell);
|
||||||
|
|
||||||
if (server != NULL && strcmp("www.mediafire.com", server) != 0)
|
if (mfshell_user_options.server != NULL)
|
||||||
free(server);
|
free(mfshell_user_options.server);
|
||||||
if (username != NULL)
|
if (mfshell_user_options.username != NULL)
|
||||||
free(username);
|
free(mfshell_user_options.username);
|
||||||
if (password != NULL)
|
if (mfshell_user_options.password != NULL)
|
||||||
free(password);
|
free(mfshell_user_options.password);
|
||||||
if (command != NULL)
|
if (mfshell_user_options.command != NULL)
|
||||||
free(command);
|
free(mfshell_user_options.command);
|
||||||
|
if (mfshell_user_options.config != NULL)
|
||||||
|
free(mfshell_user_options.config);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,4 +17,8 @@ esac
|
|||||||
|
|
||||||
cmd="valgrind --suppressions="${source_dir}/valgrind.supp" --fullpath-after="$source_dir" --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes"
|
cmd="valgrind --suppressions="${source_dir}/valgrind.supp" --fullpath-after="$source_dir" --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes"
|
||||||
|
|
||||||
$cmd "${binary_dir}/mediafire-shell" -c "help; whoami"
|
if [ ! -f "./.mediafire-tools.conf" -a ! -f "~/.mediafire-tools.conf" ]; then
|
||||||
|
echo "no configuration file found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
$cmd "${binary_dir}/mediafire-shell" -c "help; ls; whoami"
|
||||||
|
|||||||
Reference in New Issue
Block a user