· 5 years ago · Aug 12, 2020, 08:50 PM
1e <stdbool.h>
2#include <stdlib.h>
3#include <curl/curl.h>
4
5// 32 byte api key
6// can be found at https://pastebin.com/api#1 while logged in
7#define API_DEV_KEY "85775ec7499f74ab87344ca7ba61c95a"
8
9#include "log.h"
10
11const char *argp_program_version = "pb v0.1";
12const char *argp_program_bug_address = "<kilo@meters.sh>";
13static char doc[] = "Allows you to quickly post files to pastebin";
14static char args_doc[] = "[FILENAME]...";
15static struct argp_option options[] = {
16 { "edit", 'e', 0, 0, "Open a file with $EDITOR in /tmp/ then upload it"},
17 { "filetype", 'f', 0, 0, "Manually set filetype"},
18 { 0 }
19};
20
21struct arguments {
22 char *file;
23 char *filetype;
24 bool use_editor;
25};
26
27static error_t parse_opt(int key, char *arg, struct argp_state *state) {
28 struct arguments *arguments = state->input;
29 switch (key) {
30 case 'e': arguments->use_editor = true; break;
31 case 'f': arguments->filetype = "python"; break;
32 case ARGP_KEY_ARG: arguments->file = arg; break;
33 default: return ARGP_ERR_UNKNOWN;
34 }
35 return 0;
36}
37
38static struct argp argp = { options, parse_opt, args_doc, doc, 0, 0, 0 };
39
40static bool upload_file(FILE *stream, char *filetype) {
41 bool success = true;
42 CURL *curl = curl_easy_init();
43 if (!curl) {
44 log_error("Could not initalize cURL.");
45 return false;
46 }
47
48 // Get file size
49 fseek(stream, 0L, SEEK_END);
50 unsigned long buffer_size = ftell(stream);
51 rewind(stream);
52
53 log_debug("test");
54 // Another approach would be to allocate 3*buffer_size+77 which would be the
55 // theoretical maximum size a buffer could be to save a realloc.
56 char *buffer = malloc(sizeof(char) * buffer_size);
57
58 log_debug("test");
59 // read whole file into buffer
60 fread(buffer, sizeof(char), buffer_size-1, stream);
61 buffer[buffer_size-1] = '\0';
62
63 log_debug("test");
64 char *encoded_buffer = curl_easy_escape(curl, buffer, buffer_size);
65 puts(encoded_buffer);
66 /* puts(encoded_buffer); */
67
68 unsigned long post_data_size = strlen(encoded_buffer) + 512;
69 char *post_data = realloc(encoded_buffer, post_data_size); // (char*) malloc(77 + strlen(url_encoded_data));
70
71 log_debug("test");
72 snprintf(post_data, post_data_size, "api_dev_key=" API_DEV_KEY "&api_option=paste&api_paste_format=%s&api_paste_code=%s", filetype, encoded_buffer);
73
74 log_debug("test");
75 curl_easy_setopt(curl, CURLOPT_URL, "https://pastebin.com/api/api_post.php");
76 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data);
77
78 CURLcode res = curl_easy_perform(curl);
79
80 log_debug("test");
81 if (res != CURLE_OK) {
82 log_error("Request to Pastebin's servers failed: %s\n", curl_easy_strerror(res));
83 success = false;
84 }
85
86 log_debug("test");
87
88 free(buffer);
89 free(encoded_buffer);
90 curl_easy_cleanup(curl);
91
92 return success;
93}
94
95static char *guess_filetype(char *filename) {
96 char c;
97
98 bool in_filetype;
99 char *filetype_buffer = malloc(sizeof(char) * strlen(filename));
100 unsigned int i = 0;
101
102 while ((c = *filename++) != '\0') {
103 if (c == '.') {
104 if (in_filetype) {
105 i = 0;
106 }
107 else {
108 in_filetype = true;
109 }
110 } else if (in_filetype) {
111 filetype_buffer[i] = c;
112 i++;
113 }
114 }
115
116 filetype_buffer[i+1] = '\0';
117
118 if (in_filetype == false) {
119 return NULL;
120 }
121
122 return filetype_buffer;
123}
124
125int main(int argc, char **argv) {
126 struct arguments arguments;
127
128 arguments.file = "";
129 arguments.filetype = "";
130 arguments.use_editor = false;
131
132 argp_parse(&argp, argc, argv, 0, 0, &arguments);
133
134 if (strlen(arguments.file) == 0) {
135 log_error("A file is required.");
136 return 1;
137 }
138
139 char *filetype;
140 if (strlen(arguments.filetype) == 0) {
141 filetype = guess_filetype(arguments.file);
142
143 if (filetype == NULL) {
144 log_warning("Could not guess filetype from filename, defaulting to \"txt\"");
145 filetype = "txt";
146 }
147 }
148
149 FILE *fp = fopen(arguments.file, "r");
150
151 if (fp == NULL) {
152 log_error("Could not find file \"%s\"", arguments.file);
153 return 1;
154 }
155
156 bool res = upload_file(fp, filetype);
157
158 return 0;
159}