-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
357 additions
and
311 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#ifndef ANNOUNCEMENT_H | ||
#define ANNOUNCEMENT_H | ||
#include <command.h> | ||
|
||
int make_announcement_command_func(struct command *cur, int argc, char **argv); | ||
|
||
struct command make_announcement_command; | ||
|
||
#endif // ANNOUNCEMENT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#ifndef CLIENT_H | ||
#define CLIENT_H | ||
|
||
#include <curl/curl.h> | ||
#include <sr_keychain.h> | ||
|
||
#ifndef NDEBUG | ||
#define TARGET_URL "http://judge_ui:8888" | ||
#else | ||
#define TARGET_URL "https://judge.eluminatis-of-lu.com" | ||
#endif | ||
|
||
#define target_url(x) TARGET_URL "/" x | ||
|
||
CURL *curl; | ||
|
||
|
||
void init_curl(void); | ||
void cleanup_curl(void); | ||
void print_cookies(void); | ||
void save_cookies(void); | ||
size_t noop_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata); | ||
|
||
#endif // CLIENT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#ifndef COMMAND_H | ||
#define COMMAND_H | ||
|
||
struct command | ||
{ | ||
const char *name; | ||
const char *desc; | ||
const char *help; | ||
struct command *sub; | ||
int (*func)(struct command *cur, int argc, char **argv); | ||
}; | ||
|
||
void print_help(struct command *cmd); | ||
|
||
int print_help_and_traverse(struct command *cur, int argc, char **argv); | ||
|
||
void cleanup_commands(struct command *cmd); | ||
|
||
#endif // COMMAND_H |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#ifndef LOGIN_H | ||
#define LOGIN_H | ||
#include <command.h> | ||
|
||
int login_command_func(struct command *cur, int argc, char **argv); | ||
|
||
struct command login_command; | ||
|
||
#endif // LOGIN_H |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#include <announcement.h> | ||
#include <client.h> | ||
#include <stdbool.h> | ||
#include <ketopt.h> | ||
|
||
struct command make_announcement_command = { | ||
.name = "make-announcement", | ||
.desc = "make an announcement", | ||
.help = "make-announcement --message [message]", | ||
.sub = NULL, | ||
.func = make_announcement_command_func, | ||
}; | ||
|
||
int make_announcement_command_func(struct command *cur, int argc, char **argv) | ||
{ | ||
static ko_longopt_t make_announcement_longopts[] = { | ||
{"message", 1, 0}, | ||
{"help", 0, 0}, | ||
{0, 0, 0}}; | ||
ketopt_t opt = KETOPT_INIT; | ||
int c; | ||
bool help = false; | ||
char *message = NULL; | ||
while ((c = ketopt(&opt, argc + 1, argv - 1, 1, "m:h", make_announcement_longopts)) != -1) | ||
{ | ||
switch (c) | ||
{ | ||
case 'm': | ||
message = curl_easy_escape(curl, opt.arg, strlen(opt.arg)); | ||
break; | ||
case 'h': | ||
help = true; | ||
break; | ||
default: | ||
break; | ||
} | ||
switch (opt.longidx) | ||
{ | ||
case 0: | ||
message = curl_easy_escape(curl, opt.arg, strlen(opt.arg)); | ||
break; | ||
case 1: | ||
help = true; | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
help = help || !message; | ||
if (help) | ||
{ | ||
print_help(cur); | ||
} | ||
if (!help) | ||
{ | ||
char postdata[1024]; | ||
snprintf(postdata, 1023, "message=%s", message); | ||
curl_easy_setopt(curl, CURLOPT_URL, target_url("api/v1/announcement")); | ||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata); | ||
CURLcode res = curl_easy_perform(curl); | ||
if (res != CURLE_OK) | ||
{ | ||
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); | ||
exit(EXIT_FAILURE); | ||
} | ||
CURLcode http_code; | ||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); | ||
if (!(http_code == 200 && res != CURLE_ABORTED_BY_CALLBACK)) | ||
{ | ||
fprintf(stderr, "make announcement failed\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
printf("make announcement success\n"); | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#include <client.h> | ||
#include <stdio.h> | ||
|
||
void init_curl(void) | ||
{ | ||
curl = curl_easy_init(); | ||
atexit(cleanup_curl); | ||
if (curl == NULL) | ||
{ | ||
fprintf(stderr, "Failed to initialize curl\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); | ||
|
||
char *cookie = NULL; | ||
if (!sr_keychain_get_password(TARGET_URL, "socli", &cookie)) | ||
{ | ||
curl_easy_setopt(curl, CURLOPT_COOKIELIST, cookie); | ||
free(cookie); | ||
} | ||
|
||
#ifdef NDEBUG | ||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, noop_write_callback); | ||
#else | ||
#endif | ||
} | ||
|
||
void cleanup_curl(void) | ||
{ | ||
if (curl) | ||
curl_easy_cleanup(curl); | ||
} | ||
|
||
void print_cookies(void) | ||
{ | ||
struct curl_slist *cookies; | ||
CURLcode rev = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies); | ||
if (cookies) | ||
{ | ||
for (struct curl_slist *cookie = cookies; cookie; cookie = cookie->next) | ||
{ | ||
printf("%s\n", cookie->data); | ||
} | ||
curl_slist_free_all(cookies); | ||
} | ||
} | ||
|
||
void save_cookies(void) | ||
{ | ||
struct curl_slist *cookies; | ||
curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies); | ||
if (cookies) | ||
{ | ||
for (struct curl_slist *cookie = cookies; cookie; cookie = cookie->next) | ||
{ | ||
if (sr_keychain_set_password(TARGET_URL, "socli", cookie->data)) | ||
{ | ||
fprintf(stderr, "Failed to save cookie to keyring.\n"); | ||
} | ||
} | ||
curl_slist_free_all(cookies); | ||
} | ||
} | ||
|
||
size_t noop_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) | ||
{ | ||
return size * nmemb; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <stb_ds.h> | ||
#include "command.h" | ||
|
||
void print_help(struct command *cmd) | ||
{ | ||
printf("%s\n", cmd->name); | ||
printf("%s\n", cmd->desc); | ||
printf("%s\n", cmd->help); | ||
for (int i = 0; i < arrlen(cmd->sub); ++i) | ||
{ | ||
printf(" %s\n", cmd->sub[i].name); | ||
} | ||
} | ||
|
||
int print_help_and_traverse(struct command *cur, int argc, char **argv) | ||
{ | ||
if (argc == 0) | ||
{ | ||
print_help(cur); | ||
return 0; | ||
} | ||
for (int i = 0; i < arrlen(cur->sub); ++i) | ||
{ | ||
if (strcmp(argv[0], cur->sub[i].name) == 0) | ||
{ | ||
return cur->sub[i].func(&cur->sub[i], argc - 1, argv + 1); | ||
} | ||
} | ||
print_help(cur); | ||
return -1; | ||
} | ||
|
||
void cleanup_commands(struct command *cmd) | ||
{ | ||
for (int i = 0; i < arrlen(cmd->sub); ++i) | ||
{ | ||
cleanup_commands(&cmd->sub[i]); | ||
} | ||
arrfree(cmd->sub); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#include <login.h> | ||
#include <ketopt.h> | ||
#include <stdbool.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <client.h> | ||
|
||
struct command login_command = { | ||
.name = "login", | ||
.desc = "login to SeriousOJ", | ||
.help = "login --username [username] --password [password]", | ||
.sub = NULL, | ||
.func = login_command_func, | ||
}; | ||
|
||
char *username = NULL, *password = NULL; | ||
|
||
void free_login_memory(void) | ||
{ | ||
if (username) | ||
curl_free(username); | ||
if (password) | ||
curl_free(password); | ||
} | ||
|
||
int login_command_func(struct command *cur, int argc, char **argv) | ||
{ | ||
atexit(free_login_memory); | ||
static ko_longopt_t login_longopts[] = { | ||
{"username", 1, 0}, | ||
{"password", 1, 0}, | ||
{"help", 0, 0}, | ||
{0, 0, 0}}; | ||
ketopt_t opt = KETOPT_INIT; | ||
int c; | ||
bool help = false; | ||
while ((c = ketopt(&opt, argc + 1, argv - 1, 1, "u:p:h", login_longopts)) != -1) | ||
{ | ||
switch (c) | ||
{ | ||
case 'u': | ||
username = curl_easy_escape(curl, opt.arg, strlen(opt.arg)); | ||
break; | ||
case 'p': | ||
password = curl_easy_escape(curl, opt.arg, strlen(opt.arg)); | ||
break; | ||
case 'h': | ||
help = true; | ||
break; | ||
default: | ||
break; | ||
} | ||
switch (opt.longidx) | ||
{ | ||
case 0: | ||
username = curl_easy_escape(curl, opt.arg, strlen(opt.arg)); | ||
break; | ||
case 1: | ||
password = curl_easy_escape(curl, opt.arg, strlen(opt.arg)); | ||
break; | ||
case 2: | ||
help = true; | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
help = help || !username || !password; | ||
if (help) | ||
{ | ||
print_help(cur); | ||
} | ||
if (!help) | ||
{ | ||
char postdata[1024]; | ||
snprintf(postdata, 1023, "uname=%s&password=%s", username, password); | ||
curl_easy_setopt(curl, CURLOPT_URL, target_url("login")); | ||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata); | ||
CURLcode res = curl_easy_perform(curl); | ||
if (res != CURLE_OK) | ||
{ | ||
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); | ||
exit(EXIT_FAILURE); | ||
} | ||
CURLcode http_code; | ||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); | ||
if (!(http_code == 302 && res != CURLE_ABORTED_BY_CALLBACK)) | ||
{ | ||
fprintf(stderr, "login failed\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
printf("login success\n"); | ||
save_cookies(); | ||
} | ||
return 0; | ||
} |
Oops, something went wrong.