diff options
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/asprintf.c | 1 | ||||
-rw-r--r-- | src/login.c | 14 | ||||
-rw-r--r-- | src/main.c | 15 | ||||
-rw-r--r-- | src/post.c | 42 | ||||
-rw-r--r-- | src/post.h | 2 | ||||
-rw-r--r-- | src/upload_file.c | 75 | ||||
-rw-r--r-- | src/upload_file.h | 2 | ||||
-rw-r--r-- | src/util.c | 9 | ||||
-rw-r--r-- | src/util.h | 4 |
10 files changed, 131 insertions, 35 deletions
diff --git a/src/Makefile b/src/Makefile index f7e2088..73075a6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ # demiurge makefile TARGET = demiurge -OBJS = login.o util.o post.o main.o +OBJS = login.o util.o post.o main.o upload_file.o CC = cc CFLAGS = -O2 -march=native -MD -std=c11 -Wall -Wextra -lcurl -lreadline -ljson-c diff --git a/src/asprintf.c b/src/asprintf.c index e5a6f1a..28b7f8f 100644 --- a/src/asprintf.c +++ b/src/asprintf.c @@ -32,6 +32,5 @@ vasprintf(char **restrict strp, const char *restrict fmt, return -1; va_end(args); - return size = vsprintf(*strp,fmt,ap); } diff --git a/src/login.c b/src/login.c index c0b431d..3af1b64 100644 --- a/src/login.c +++ b/src/login.c @@ -4,18 +4,9 @@ #include <stdlib.h> #include <curl/curl.h> #include <readline/readline.h> -#include "asprintf.h" - #include <json-c/json.h> - -size_t -write_data(void *buffer, size_t size, size_t nmemb, void *userp) -{ - - memcpy(userp,buffer,nmemb*size); - return 0; -} - +#include "asprintf.h" +#include "util.h" void store_config(const char *instance, const char *client_id, @@ -53,7 +44,6 @@ setup() return -1; } - int len = strlen(instance) + strlen(api_url) + 1; char buf[8192]; char *post_url = NULL; @@ -7,13 +7,14 @@ #include "login.h" #include "util.h" #include "post.h" +#include "upload_file.h" /* prints usage */ void usage(const char *progname) { - printf("Usage: %s -s=status [-v=visibility]\n",progname); + printf("Usage: %s -s=status [-v=visibility] [-F=filename]\n",progname); return; } /* prints a string to stderr */ @@ -31,13 +32,13 @@ main(int argc, char **argv) int c; char *status = NULL; char *visibility = NULL; - + char *id_ptr = NULL; if(argc == 1) { usage(argv[0]); return -1; } - while((c = getopt(argc,argv,"s:v:")) != -1) { + while((c = getopt(argc,argv,"s:v:F:")) != -1) { switch(c) { case 's': status = optarg; @@ -45,8 +46,13 @@ main(int argc, char **argv) case 'v': visibility = optarg; break; + case 'F': + upload_file(optarg,optarg,&id_ptr); + break; } + } + if(status == NULL) { eputs("Enter a status (-s)"); return -1; @@ -56,6 +62,5 @@ main(int argc, char **argv) visibility = "public"; } - post_status(status,visibility); - + post_status(status,visibility,id_ptr); } @@ -10,7 +10,7 @@ int -post_status(const char *status, const char *scope) +post_status(const char *status, const char *scope, const char *media_id) { char instance[50]; char client_id[50]; @@ -28,10 +28,6 @@ post_status(const char *status, const char *scope) char *url = NULL; asprintf(&url,"%s%s",instance,api_url); - puts(url); - - curl_easy_setopt(curl,CURLOPT_URL,url); - char *header_fmt = "Authorization: Bearer %s"; char *authorization_header = NULL; struct curl_slist *header_list = NULL; @@ -41,23 +37,39 @@ post_status(const char *status, const char *scope) curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); - char *params_fmt = "status=%s&visibility=%s"; - - char *status_to_post = NULL; - char *visibility_to_post = NULL; + curl_mime *mime; + mime = curl_mime_init(curl); + curl_mimepart *status_part, *scope_part, *media_part; + /* Is there a better way to do this? */ + + status_part = curl_mime_addpart(mime); + scope_part = curl_mime_addpart(mime); + media_part = curl_mime_addpart(mime); - char *post_params = NULL; + /* Status */ + + curl_mime_data(status_part,status,CURL_ZERO_TERMINATED); + curl_mime_name(status_part,"status"); + + /* Visibility */ + + curl_mime_data(scope_part,scope,CURL_ZERO_TERMINATED); + curl_mime_name(scope_part,"visibility"); - asprintf(&post_params,params_fmt,status,scope); + /* Media */ - curl_easy_setopt(curl,CURLOPT_POSTFIELDS,post_params); + if(media_id != NULL) { + curl_mime_data(media_part,media_id,CURL_ZERO_TERMINATED); + curl_mime_name(media_part,"media_ids[]"); + } + /* post */ + puts(url); + curl_easy_setopt(curl,CURLOPT_URL,url); + curl_easy_setopt(curl,CURLOPT_MIMEPOST,mime); curl_easy_perform(curl); free(url); - free(post_params); - free(status_to_post); - free(visibility_to_post); free(authorization_header); return 0; @@ -1,2 +1,2 @@ int -post_status(const char *status, const char *scope); +post_status(const char *status, const char *scope, const char *media_id); diff --git a/src/upload_file.c b/src/upload_file.c new file mode 100644 index 0000000..402ec6f --- /dev/null +++ b/src/upload_file.c @@ -0,0 +1,75 @@ +#include <stdio.h> +#include <stdlib.h> +#include <curl/curl.h> +#include <json-c/json.h> +#include "asprintf.h" +#include "util.h" + +int +upload_file(const char *path, const char *description, char **id_ptr) +{ + char instance[50]; + char client_id[50]; + char client_secret[50]; + char access_token[50]; + + struct json_object *parsed_json; + struct json_object *json_media_id; + char buf[8192]; + + get_tokens_from_file(".demiurgerc",instance,client_id,client_secret,access_token); + CURL *curl = curl_easy_init(); + if(curl == NULL) { + fprintf(stderr,"Error creating libcurl thing\n"); + return -1; + } + curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION, write_data); + curl_easy_setopt(curl,CURLOPT_WRITEDATA,buf); + + char *url_to_post = NULL; + asprintf(&url_to_post,"%s/api/v1/media",instance); + + /* Don't repeat yourself, so they say, it's the root of all evil + * today */ + + char *header_fmt = "Authorization: Bearer %s"; + struct curl_slist *header_list = NULL; + char *authorization_header = NULL; + asprintf(&authorization_header,header_fmt,access_token); + header_list = curl_slist_append(header_list, authorization_header); + + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); + + curl_mime *mime; + mime = curl_mime_init(curl); + curl_mimepart *image_part; + image_part = curl_mime_addpart(mime); + curl_mimepart *description_part; + description_part = curl_mime_addpart(mime); + /* Upload file */ + + curl_mime_filedata(image_part, path); + curl_mime_name(image_part,"file"); + + /* Description */ + + curl_mime_data(description_part,description,CURL_ZERO_TERMINATED); + curl_mime_name(description_part,"description"); + + /* Post */ + + curl_easy_setopt(curl,CURLOPT_MIMEPOST,mime); + curl_easy_setopt(curl,CURLOPT_URL,url_to_post); + + /* Free the things */ + curl_easy_perform(curl); + free(url_to_post); + curl_easy_cleanup(curl); + curl_mime_free(mime); + /* Get the media id */ + parsed_json = json_tokener_parse(buf); + json_object_object_get_ex(parsed_json, "id", &json_media_id); + const char *media_id = json_object_get_string(json_media_id); + *id_ptr = media_id; + return 0; +} diff --git a/src/upload_file.h b/src/upload_file.h new file mode 100644 index 0000000..5ac0cf0 --- /dev/null +++ b/src/upload_file.h @@ -0,0 +1,2 @@ +int +upload_file(const char *path, const char *description, char **id_ptr); @@ -1,4 +1,5 @@ #include <stdio.h> +#include <string.h> /* This function fucking sucks and should use something else. I'll * have to rewrite this shit function some day. But for now, it will @@ -23,3 +24,11 @@ get_tokens_from_file(char *filename, char *instance, char *client_id, return 0; } + +size_t +write_data(void *buffer, size_t size, size_t nmemb, void *userp) +{ + + memcpy(userp,buffer,nmemb*size); + return 0; +} @@ -1,3 +1,7 @@ +#include <stdlib.h> + int get_tokens_from_file(char *filename, char *instance,char *client_id, char *client_secret, char *access_token); +size_t +write_data(void *buffer, size_t size, size_t nmemb, void *userp); |