#define _BSD_SOURCE /* Needed for popen(3) on Linux. */ #include #include #include #include #include #include "config.h" char *url = "https://sdccd.instructure.com/api/v1/users/self/files"; char * json_match(char *JSON, char *key) { char *p = strstr(JSON, key); if (p == NULL) { return NULL; } p += strlen(key) + strlen("\":\""); int len = 0, i; for (i = 0; p[i] != '\0' && p[i] != '"'; i++) { len++; } char *val = calloc(len + 1, sizeof(char)); for (i = 0; i < len; i++) { val[i]= p[i]; } val[len] = '\0'; return val; } char * strip_fn(char *path) { char *dir = calloc(strlen(path) + 1, sizeof(char)); strcpy(dir, path); int i; for (i = strlen(path) - 1; i >= 0; i--) { if (dir[i] == '/') { dir[i] = '\0'; return dir; } } dir[0] = '\0'; return dir; } int upfile(char *name, char *rdir) { printf("%s/%s\n", rdir, name); char *cmd = calloc(cmdsize, sizeof(char)); char *dir = strip_fn(name); snprintf(cmd, cmdsize, "curl -s '%s' -F 'name=%s'" " -F 'parent_folder_path=%s/%s'" " -H 'Authorization: Bearer %s'", url, name, rdir, dir, upload_key); FILE *auth = popen(cmd, "r"); char *JSON = NULL; int len = 0; char ch; while ((ch = fgetc(auth)) > 0) { len++; JSON = realloc(JSON, len * sizeof(char)); JSON[len - 1] = ch; } len++; JSON = realloc(JSON, len * sizeof(char)); /* Test output. JSON = "{\"file_param\":\"file\",\"progress\":null,\"upload_url\":\"https://inst-fs-iad-prod.inscloudgate.net/files?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2OTMwNzEwMDYsInVzZXJfaWQiOiIxMDY5MDAwMDAwOTA2NDk1MCIsInJlc291cmNlIjoiL2ZpbGVzIiwiY2FwdHVyZV91cmwiOiJodHRwczovL3NkY2NkLmluc3RydWN0dXJlLmNvbS9hcGkvdjEvZmlsZXMvY2FwdHVyZSIsImNhcHR1cmVfcGFyYW1zIjp7ImNvbnRleHRfdHlwZSI6IlVzZXIiLCJjb250ZXh0X2lkIjoiMTA2OTAwMDAwMDkwNjQ5NTAiLCJ1c2VyX2lkIjoiMTA2OTAwMDAwMDkwNjQ5NTAiLCJmb2xkZXJfaWQiOiIxMDY5MDAwMDAxNzQ2MTcyMiIsInJvb3RfYWNjb3VudF9pZCI6IjEwNjkwMDAwMDAwMDgxMjg0IiwicXVvdGFfZXhlbXB0IjpmYWxzZSwib25fZHVwbGljYXRlIjoib3ZlcndyaXRlIiwicHJvZ3Jlc3NfaWQiOm51bGwsImluY2x1ZGUiOm51bGx9LCJsZWdhY3lfYXBpX2RldmVsb3Blcl9rZXlfaWQiOiIxNzAwMDAwMDAwMDAwMTYiLCJsZWdhY3lfYXBpX3Jvb3RfYWNjb3VudF9pZCI6IjEwNjkwMDAwMDAwMDgxMjg0IiwiZXhwIjoxNjkzMDcxNjA2fQ.emC3105zbRiley3teCUsym5jVLmOePaENMahQ-MQRthgawN0GAuG9ufUYyk0l7hrXKy2WYaO0v3m6pmIkA3s4w\",\"upload_params\":{\"filename\":\"test.txt\",\"content_type\":\"text/plain\"}}";*/ char *upload_url = json_match(JSON, "upload_url"); char *content_type = json_match(JSON, "content_type"); char *filename = json_match(JSON, "filename"); if (upload_url == NULL || content_type == NULL || filename == NULL) { fprintf(stderr, "Something went wrong with" "authentification.\n%s\n", JSON); return -1; } snprintf(cmd, cmdsize, "curl -s '%s' -F 'key=%s'" " -F 'content_type=%s' -F 'file=@%s'", upload_url, filename, content_type, name); /* Throw away output; assume that, if auth is successful, then upload is successful too. */ popen(cmd, "r"); free(upload_url); free(content_type); free(filename); free(dir); free(cmd); return 0; } int updir(DIR *dirp, char *rdir, char *dir) { DIR *nestdirp; struct dirent *dp; char *name = calloc(pathsize, sizeof(char)); while ((dp = readdir(dirp)) != NULL) { if (strcmp(".", dp->d_name) == 0 || strcmp("..", dp->d_name) == 0) continue; if (strcmp(".", dir) != 0) { strcpy(name, dir); if (name[strlen(name) - 1] != '/') strcat(name, "/"); strcat(name, dp->d_name); } else strcpy(name, dp->d_name); nestdirp = opendir(name); if (nestdirp == NULL) upfile(name, rdir); else if (nestdirp != NULL) { updir(nestdirp, rdir, name); } } free(name); closedir(dirp); return 0; } int main(int argc, char **argv) { upload_key = getenv("CANKEY"); if (upload_key == NULL) { fprintf(stderr, "Provide a valid key in the" " environment variable CANKEY.\nUsing a POSIX shell," " do this in ~/.profile.\n" " Using rc, do this in $home/lib/profile.\n"); return -1; } char *rdir; rdir = calloc(pathsize, sizeof(char)); char *local; local = calloc(pathsize, sizeof(char)); local[0] = '.'; int i; for (i = 1; i < argc; ++i) { if (strcmp(argv[i], "-r") == 0) { if (i < argc - 1) { ++i; rdir = argv[i]; } else { puts("Supply a directory" " name after -r"); return 1; } } else if (strcmp(argv[i], "-f") == 0) { if (i < argc - 1) { ++i; local = argv[i]; } else { puts("Supply a file or directory" " name after -f"); return 2; } } else { puts(argv[i]); printf("%s [-r remote directory]" " [-f local file or directory]\n", argv[0]); return -1; } } DIR *dirp = opendir(local); if (dirp != NULL) { updir(dirp, rdir, local); } else if (access(local, R_OK) == 0) { upfile(local, rdir); } else { printf("I can't open this!\n"); return 3; } return 0; }