PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/ficiauploader.c

https://github.com/yappo/ficiauploader
C | 263 lines | 202 code | 38 blank | 23 comment | 49 complexity | f1744d0d907a0e3c822adbe0c3942ddd MD5 | raw file
  1. /*
  2. MIT LICENSE
  3. copyright kazuhiro osawa
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <curl/curl.h>
  9. #include <sys/stat.h>
  10. #define DEBUG 0
  11. #define VERSION_STR "0.01"
  12. #define API_LOGINNAME "ficia"
  13. #define API_ENDPOINT "http://ficia.com/api/gr2/eyefi/main.php"
  14. #define GR2_STATUS_LOGIN_OK "#__GR2PROTO__\nserver_version=2.11\nstatus=0\nstatus_text=OK\n"
  15. #define GR2_STATUS_UPLOAD_OK "#__GR2PROTO__\nstatus=0\nstatus_text=OK\n"
  16. typedef struct {
  17. int len;
  18. char *buf;
  19. } gallery2_text;
  20. static void usage(void)
  21. {
  22. fputs("ficiauploader\n"
  23. "\n"
  24. "Usage: ficiauploader [options]\n"
  25. "\n"
  26. "Environment Variable:\n"
  27. "FICIA_PASSWORD your ficia eye-fi password\n"
  28. "\n"
  29. "Options:\n"
  30. " -f <upload file> upload file\n"
  31. " -h displays this help message\n"
  32. " -v displays version number\n"
  33. "\n"
  34. "Examples:\n"
  35. " $ export FICIA_PASSWORD=xxxxxxxx ficiauploader -f example.jpg\n",
  36. stdout);
  37. exit(0);
  38. }
  39. static void show_version(void)
  40. {
  41. fputs("ficiauploader " VERSION_STR "\n"
  42. "\n"
  43. "Copyright (C) Kazuhiro Osawa\n",
  44. stdout);
  45. exit(0);
  46. }
  47. size_t writefunction_callback(void *ptr, size_t size ,size_t nmemb, gallery2_text *text)
  48. {
  49. int ptrsize = size * nmemb;
  50. text->len += ptrsize;
  51. if ((text->buf = realloc(text->buf, text->len + 1)) == NULL) {
  52. fprintf(stderr, "memory allocation error\n");
  53. exit(-1);
  54. }
  55. memcpy(text->buf + text->len - ptrsize, ptr, ptrsize);
  56. text->buf[text->len] = '\0';
  57. return ptrsize;
  58. }
  59. int gallery2_response_success(gallery2_text *text) {
  60. if (!text->buf) return 0;
  61. /* login */
  62. if (strlen(text->buf) == strlen(GR2_STATUS_LOGIN_OK)) {
  63. if (strcmp(text->buf, GR2_STATUS_LOGIN_OK) == 0) return 1;
  64. return 2;
  65. }
  66. /* upload */
  67. text->buf[strlen(GR2_STATUS_UPLOAD_OK)] = '\0';
  68. if (strcmp(text->buf, GR2_STATUS_UPLOAD_OK) != 0) return 0;
  69. return 1;
  70. }
  71. int gallery2_login(CURL *curl, char *login_name, char *login_password) {
  72. CURLcode ret;
  73. struct curl_httppost *post = NULL;
  74. struct curl_httppost *last = NULL;
  75. gallery2_text response;
  76. bzero(&response, sizeof(gallery2_text));
  77. curl_formadd(&post, &last,
  78. CURLFORM_COPYNAME, "g2_controller",
  79. CURLFORM_COPYCONTENTS, "remote:GalleryRemote",
  80. CURLFORM_END);
  81. curl_formadd(&post, &last,
  82. CURLFORM_COPYNAME, "g2_form[cmd]",
  83. CURLFORM_COPYCONTENTS, "login",
  84. CURLFORM_END);
  85. curl_formadd(&post, &last,
  86. CURLFORM_COPYNAME, "g2_form[uname]",
  87. CURLFORM_COPYCONTENTS, login_name,
  88. CURLFORM_END);
  89. curl_formadd(&post, &last,
  90. CURLFORM_COPYNAME, "g2_form[password]",
  91. CURLFORM_COPYCONTENTS, login_password,
  92. CURLFORM_END);
  93. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunction_callback);
  94. curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response);
  95. curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
  96. ret = curl_easy_perform(curl);
  97. curl_formfree(post);
  98. if (ret != 0) {
  99. if (response.buf) free(response.buf);
  100. return 0;
  101. }
  102. if (gallery2_response_success(&response) == 0) {
  103. if (response.buf) free(response.buf);
  104. return 0;
  105. }
  106. if (response.buf) free(response.buf);
  107. return 1;
  108. }
  109. int gallery2_upload(CURL *curl, char *filename) {
  110. CURLcode ret;
  111. struct curl_httppost *post = NULL;
  112. struct curl_httppost *last = NULL;
  113. char *p, *basename, *buf;
  114. struct stat s;
  115. FILE *fp;
  116. gallery2_text response;
  117. bzero(&response, sizeof(gallery2_text));
  118. bzero(&s, sizeof(s));
  119. stat(filename, &s);
  120. if ((s.st_mode & S_IFMT) == 0) {
  121. fprintf(stderr, "No such file or directory: %s\n", filename);
  122. return 0;
  123. }
  124. /*
  125. buf = calloc(s.st_size, sizeof(char));
  126. if (buf == NULL) return 0;
  127. if ((fp = fopen(filename, "rb")) == NULL) return 0;
  128. if (fread(buf, 1, s.st_size, fp) != s.st_size) return 0;
  129. */
  130. p = filename + strlen(filename);
  131. while (p != filename) {
  132. if (*p == '/') {
  133. p++;
  134. break;
  135. }
  136. p--;
  137. }
  138. basename = p;
  139. if (strlen(basename) == 0) {
  140. fprintf(stderr, "cannot detected file name: %s\n", filename);
  141. return 0;
  142. }
  143. curl_formadd(&post, &last,
  144. CURLFORM_COPYNAME, "g2_controller",
  145. CURLFORM_COPYCONTENTS, "remote:GalleryRemote",
  146. CURLFORM_END);
  147. curl_formadd(&post, &last,
  148. CURLFORM_COPYNAME, "g2_form[cmd]",
  149. CURLFORM_COPYCONTENTS, "add-item",
  150. CURLFORM_END);
  151. curl_formadd(&post, &last,
  152. CURLFORM_COPYNAME, "g2_userfile_name",
  153. CURLFORM_COPYCONTENTS, basename,
  154. CURLFORM_END);
  155. curl_formadd(&post, &last,
  156. CURLFORM_COPYNAME, "g2_userfile",
  157. CURLFORM_FILE, filename, CURLFORM_END);
  158. /*
  159. curl_formadd(&post, &last,
  160. CURLFORM_COPYNAME, "g2_userfile",
  161. CURLFORM_PTRCONTENTS, buf,
  162. CURLFORM_CONTENTSLENGTH, s.st_size,
  163. CURLFORM_CONTENTTYPE, "image/jpeg",
  164. CURLFORM_FILECONTENT, "ageage.jpg",
  165. CURLFORM_CONTENTHEADER, headers,
  166. CURLFORM_END);
  167. */
  168. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunction_callback);
  169. curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response);
  170. curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
  171. ret = curl_easy_perform(curl);
  172. curl_formfree(post);
  173. if (ret != 0) {
  174. if (response.buf) free(response.buf);
  175. return 0;
  176. }
  177. if (gallery2_response_success(&response) == 0) {
  178. if (response.buf) free(response.buf);
  179. return 0;
  180. }
  181. if (response.buf) free(response.buf);
  182. return 1;
  183. }
  184. int main(int argc, char **argv)
  185. {
  186. CURL *curl;
  187. CURLcode ret;
  188. char *login_name, *login_password;
  189. char *filename = NULL;
  190. /* parse args */
  191. argv++;
  192. while (*argv != NULL && argv[0][0] == '-') {
  193. char *arg = *argv++;
  194. if (strcmp(arg, "-f") == 0) {
  195. filename = *argv++;
  196. } else if (strcmp(arg, "-v") == 0) {
  197. show_version();
  198. } else if (strcmp(arg, "-h") == 0) {
  199. usage();
  200. }
  201. }
  202. if (filename == NULL) usage();
  203. login_name = API_LOGINNAME;
  204. login_password = getenv("FICIA_PASSWORD");
  205. curl = curl_easy_init();
  206. if (!curl) {
  207. fprintf(stderr, "couldn't init curl\n");
  208. return 0;
  209. }
  210. if (DEBUG) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
  211. curl_easy_setopt(curl, CURLOPT_COOKIESESSION, 1);
  212. curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
  213. curl_easy_setopt(curl, CURLOPT_URL, API_ENDPOINT);
  214. if (!gallery2_login(curl, login_name, login_password)) {
  215. fprintf(stderr, "couldn't login\n");
  216. return 0;
  217. }
  218. if (!gallery2_upload(curl, filename)) {
  219. fprintf(stderr, "couldn't file upload\n");
  220. return 0;
  221. }
  222. fprintf(stdout, "uploaded: %s\n", filename);
  223. curl_easy_cleanup(curl);
  224. return 0;
  225. }