int main(int argc, char **argv) { long cookie_expire; int ret = 1; config = config_new(); if (curl_init() != 0) { fprintf(stderr, "Error: An error occurred while initializing curl\n"); goto finish; } ret = parseargs(argc, argv); if (ret != 0) { return 1; } if (config->category) { config->catnum = category_is_valid(config->category); if (config->catnum < 0) { usage_categories(); goto finish; } } else { config->catnum = 1; } if (optind == argc) { fprintf(stderr, "error: no packages specified (use -h for help)\n"); goto finish; } /* We can't read the config file without having verbosity set, but the * command line options need to take precedence over the config. file. * Therefore, if ((user && pass) || cookie file) is supplied on the command * line, we won't read the config file. */ if (!(config->user || config->cookie_file)) { read_config_file(); } if (cookie_setup() != 0) { goto finish; } cookie_expire = cookie_expire_time(config->cookie_file, AUR_DOMAIN, AUR_COOKIE_NAME); if (cookie_expire > 0) { if (time(NULL) < cookie_expire) { config->cookie_valid = 1; } else { fprintf(stderr, "Your cookie has expired. Gathering user and password...\n"); } } if (!config->cookie_valid) { if (!config->cmdline_user && !config->user) { config->user = read_stdin("Enter username", AUR_USER_MAX, 1); if (!config->user || !strlen(config->user)) { fprintf(stderr, "error: invalid username supplied\n"); goto finish; } } if (!config->password || (config->cmdline_user && !config->cmdline_passwd)) { printf("[%s] ", config->user); config->password = read_stdin("Enter password", AUR_PASSWORD_MAX, 0); } } if (config->cookie_valid || aur_login() == 0) { char *csrf_token; /* booo, stupid hacks. curl doesn't prime curl_slist of cookies * we want via CURLINFO_COOKIELIST until we call perform at least * once. */ prime_cookielist(); csrf_token = get_csrf_token(); if (csrf_token == NULL) { fprintf(stderr, "failed to obtain CSRF token for uploading\n"); goto finish; } ret = 0; while (optind < argc) { int r = aur_upload(argv[optind++], csrf_token); if (r != 0) { ret = r; } } free(csrf_token); } finish: if (config->cookie_file && !config->cookie_persist) { debug("Deleting file %s\n", config->cookie_file); unlink(config->cookie_file); } config_free(config); curl_cleanup(); return ret; }
static int parseargs(int *argc, char ***argv) { static struct option option_table[] = { { "cookies", required_argument, 0, 'C' }, { "category", required_argument, 0, 'c' }, { "expire", no_argument, 0, 'e' }, { "help", no_argument, 0, 'h' }, { "password", required_argument, 0, 'p' }, { "user", required_argument, 0, 'u' }, { "version", no_argument, 0, 'V' }, { "verbose", no_argument, 0, 'v' }, { "domain", required_argument, 0, OPT_DOMAIN }, { NULL, 0, NULL, 0 }, }; for (;;) { int opt = getopt_long(*argc, *argv, "C:c:ehp:u:Vv", option_table, NULL); if (opt < 0) break; switch (opt) { case 'C': arg_cookiefile = optarg; break; case 'c': arg_category = category_validate(optarg); if (arg_category == NULL) { log_error("invalid category %s", optarg); usage_categories(); return -EINVAL; } break; case 'e': arg_expire = true; break; case 'h': print_usage(); case 'p': arg_password = optarg; break; case 'u': arg_username = optarg; break; case 'V': print_version(); case 'v': ++arg_loglevel; break; case OPT_DOMAIN: arg_domain = optarg; break; default: return -EINVAL; } } *argv += optind; *argc -= optind; if (!arg_expire && *argc == 0) { log_error("error: no files specified (use -h for help)"); return -EINVAL; } log_set_level(arg_loglevel); return 0; }