diff options
Diffstat (limited to 'client.c')
-rw-r--r-- | client.c | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/client.c b/client.c new file mode 100644 index 0000000..d90ac42 --- /dev/null +++ b/client.c @@ -0,0 +1,304 @@ +#ifdef DEBUG +#ifdef ANDROID +#include <android/log.h> +#else +#include <stdio.h> +#endif // ANDROID +#endif // DEBUG +#include <stdlib.h> +#include <string.h> +#include <curl/curl.h> +#include "rtclient/rtclient.h" + +typedef struct rt_user rt_user; +typedef struct rt_ticketlist rt_ticketlist; +static CURL *curl = NULL; +static char *server_url = NULL; + +bool rtclient_init(const char *url) +{ + curl_global_init(CURL_GLOBAL_SSL); + curl = curl_easy_init(); + if (curl) { + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); + curl_easy_setopt(curl, CURLOPT_REFERER, url); +#ifdef DEBUG + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); +#endif // DEBUG + server_url = malloc(strlen(url) + 1); + strcpy(server_url, url); + } + + return (bool)curl; +} + +static size_t +user_callback(void *contents, size_t size, size_t nmemb, void *writedata) +{ + size_t realsize = size * nmemb; + char response[realsize + 1]; + memcpy(response, contents, realsize); + response[realsize] = '\0'; + + rt_user **userptr = (rt_user **)writedata; + rt_user *user = *userptr; + + char *linesaveptr = NULL; + char *line = strtok_r(response, "\n", &linesaveptr); + if (strstr(line, "200 Ok")) { + line = strtok_r(NULL, "\n", &linesaveptr); + char *tokensaveptr = NULL, *token = NULL; + do { + token = strtok_r(line, ":", &tokensaveptr); + if (!strcmp(token, "id")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->id = malloc(strlen(token)); + strcpy(user->id, ++token); + } else if (!strcmp(token, "Password")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->password = malloc(strlen(token)); + strcpy(user->password, ++token); + } else if (!strcmp(token, "Name")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->name = malloc(strlen(token)); + strcpy(user->name, ++token); + } else if (!strcmp(token, "EmailAddress")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->emailaddress = malloc(strlen(token)); + strcpy(user->emailaddress, ++token); + } else if (!strcmp(token, "RealName")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->realname = malloc(strlen(token)); + strcpy(user->realname, ++token); + } else if (!strcmp(token, "NickName")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->nickname = malloc(strlen(token)); + strcpy(user->nickname, ++token); + } else if (!strcmp(token, "Gecos")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->gecos = malloc(strlen(token)); + strcpy(user->gecos, ++token); + } else if (!strcmp(token, "Organization")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->organization = malloc(strlen(token)); + strcpy(user->organization, ++token); + } else if (!strcmp(token, "Address1")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->address1 = malloc(strlen(token)); + strcpy(user->address1, ++token); + } else if (!strcmp(token, "Address2")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->address2 = malloc(strlen(token)); + strcpy(user->address2, ++token); + } else if (!strcmp(token, "City")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->city = malloc(strlen(token)); + strcpy(user->city, ++token); + } else if (!strcmp(token, "State")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->state = malloc(strlen(token)); + strcpy(user->state, ++token); + } else if (!strcmp(token, "Zip")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->zip = malloc(strlen(token)); + strcpy(user->zip, ++token); + } else if (!strcmp(token, "Country")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->country = malloc(strlen(token)); + strcpy(user->country, ++token); + } else if (!strcmp(token, "HomePhone")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->homephone = malloc(strlen(token)); + strcpy(user->homephone, ++token); + } else if (!strcmp(token, "WorkPhone")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->workphone = malloc(strlen(token)); + strcpy(user->workphone, ++token); + } else if (!strcmp(token, "MobilePhone")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->mobilephone = malloc(strlen(token)); + strcpy(user->mobilephone, ++token); + } else if (!strcmp(token, "PagerPhone")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->pagerphone = malloc(strlen(token)); + strcpy(user->pagerphone, ++token); + } else if (!strcmp(token, "ContactInfo")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->contactinfo = malloc(strlen(token)); + strcpy(user->contactinfo, ++token); + } else if (!strcmp(token, "Comments")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->comments = malloc(strlen(token)); + strcpy(user->comments, ++token); + } else if (!strcmp(token, "Signature")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->signature = malloc(strlen(token)); + strcpy(user->signature, ++token); + } else if (!strcmp(token, "Lang")) { + token = strtok_r(NULL, ":", &tokensaveptr); + strncpy(user->lang, ++token, 2); + } else if (!strcmp(token, "Privileged")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->privileged = (bool)atoi(++token); + } else if (!strcmp(token, "Disabled")) { + token = strtok_r(NULL, ":", &tokensaveptr); + user->disabled = (bool)atoi(++token); + } + } while ((line = strtok_r(NULL, "\n", &linesaveptr))); + } else { + free(*userptr); + *userptr = NULL; + } + + return realsize; +} + +static size_t +search_callback(void *contents, size_t size, size_t nmemb, void *writedata) +{ + size_t realsize = size * nmemb; + char response[realsize + 1]; + memcpy(response, contents, realsize); + response[realsize] = '\0'; + char lines[strlen(response) + 1]; + strcpy(lines, response); + rt_ticketlist **listptr = (rt_ticketlist **)writedata; + + char *line = strtok(response, "\n"); + if (strstr(line, "200 Ok")) { + (*listptr)->length = 0; + line = strtok(NULL, "\n"); + do { + (*listptr)->length++; + } while ((line = strtok(NULL, "\n"))); + rt_ticketlist *ptr = realloc(*listptr, sizeof(*listptr) + + (*listptr)->length * sizeof(char *)); + *listptr = ptr; + rt_ticketlist *list = *listptr; + char *linesaveptr = NULL; + line = strtok_r(lines, "\n", &linesaveptr); + line = strtok_r(NULL, "\n", &linesaveptr); + char *tokensaveptr = NULL, *token = NULL; + for (unsigned int i = 0; i < list->length; i++) { + token = strtok_r(line, ":", &tokensaveptr); + token = strtok_r(NULL, ":", &tokensaveptr); + list->tickets[i] = malloc(strlen(token)); + strcpy(list->tickets[i], ++token); + line = strtok_r(NULL, "\n", &linesaveptr); + } + } else { + free(*listptr); + *listptr = NULL; + } + + return realsize; +} + +inline static void request(const char *path, const char *suffix + , size_t (*writefunction)(void *, size_t, size_t, void *) + , void *writedata, struct curl_httppost *post) +{ + char url[strlen(server_url) + strlen(path) + strlen(suffix) + 1]; + sprintf(url, "%s%s%s", server_url, path, suffix); + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunction); + if (writedata) + curl_easy_setopt(curl, CURLOPT_WRITEDATA, writedata); + else + curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout); + if (post) + curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); + else + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); + +#ifdef DEBUG + CURLcode res = +#endif // DEBUG + curl_easy_perform(curl); +#ifdef DEBUG + if (res != CURLE_OK) { + const char *error = curl_easy_strerror(res); +#ifdef ANDROID + __android_log_print(ANDROID_LOG_ERROR, "librtclient", "%s: %s" + , __func__, error); +#else + fprintf(stderr, "%s: %s\n", __func__, error); +#endif // ANDROID + } +#endif // DEBUG +} + +void rtclient_login(const char *name, const char *password) +{ + struct curl_httppost *post, *last = NULL; + curl_formadd(&post, &last + , CURLFORM_COPYNAME, "user" + , CURLFORM_PTRCONTENTS, name + , CURLFORM_END); + curl_formadd(&post, &last + , CURLFORM_COPYNAME, "pass" + , CURLFORM_PTRCONTENTS, password + , CURLFORM_END); + last = NULL; + request("", "", NULL, NULL, post); + curl_formfree(post); + post = NULL; +} + +void rtclient_user_show(rt_user **userptr, const char *name) +{ + *userptr = malloc(sizeof(rt_user)); + request("/REST/1.0/user/", name, user_callback, (void *)userptr, NULL); +} + +void rtclient_ticket_search(rt_ticketlist **listptr, const char *query) +{ + *listptr = malloc(sizeof(rt_ticketlist)); + request("/REST/1.0/search/ticket?query=", query, search_callback + , (void *)listptr, NULL); +} + +void rtclient_user_free(rt_user *user) +{ + free(user->id); + free(user->password); + free(user->name); + free(user->emailaddress); + free(user->realname); + free(user->nickname); + free(user->gecos); + free(user->organization); + free(user->address1); + free(user->address2); + free(user->city); + free(user->state); + free(user->zip); + free(user->country); + free(user->homephone); + free(user->workphone); + free(user->mobilephone); + free(user->pagerphone); + free(user->contactinfo); + free(user->comments); + free(user->signature); + free(user); + user = NULL; +} + +void rtclient_ticket_freelist(rt_ticketlist *list) +{ + for (unsigned short i = 0; i < list->length; i++) + free(list->tickets[i]); + free(list); + list = NULL; +} + +void rtclient_cleanup() +{ + if (curl) { + free(server_url); + curl_easy_cleanup(curl); + } + curl_global_cleanup(); +} |