#include #include #include #include #include #include #include #include #include "paste.h" #define HTTP_PREFIX "http:/" #define HTTP_HOST "paste.ee" #define HTTP_PORT "80" #define BUF_SIZE 512 int main(int argc, char* argv[]) { char buffer[BUF_SIZE]; size_t contentSize = 0; char *content = malloc(sizeof(char) * BUF_SIZE); if(content == NULL) { perror("Failed to allocate content"); exit(1); } while(fgets(buffer, BUF_SIZE, stdin)) { char *old = content; contentSize += strlen(buffer); content = realloc(content, contentSize); if(content == NULL) { perror("Failed to reallocate content"); free(old); exit(2); } strcat(content, buffer); printf("%s", buffer); } char *key = getenv("PASTEE_KEY"); char *url = paste(content, key, "Paste.ee CLI Tool", NULL); printf("\nPaste URL: %s\n", url); } char *paste( char *contents, char *key, char *description, char *language ) { if(contents == NULL || contents[0] == '\0') { perror("Contents empty!"); return NULL; } struct addrinfo *result; int s = getaddrinfo(HTTP_HOST, HTTP_PORT, NULL, &result); if(s != 0) { perror("Unable to get address info"); return NULL; } int sockfd = 0, conn = 0; struct addrinfo *rp = result; do { sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sockfd <0) continue; if ((conn = connect(sockfd, rp->ai_addr, rp->ai_addrlen)) == 0) { // Success! break; } else { perror("connecting stream socket"); } close(sockfd); } while ((rp = rp->ai_next)!= NULL); if (rp == NULL) return NULL; freeaddrinfo(result); char buf[BUF_SIZE]; if(key == NULL || key[0] == '\0') { key = "public"; } if(description == NULL) { description = ""; } else { description = url_encode(description); } if(language == NULL) { language = "plain"; } size_t reqSize = sizeof(char) * (49 + strlen(description) + strlen(language) + strlen(key)); char *req = malloc(reqSize); snprintf(req, reqSize, "key=%s&format=simple&description=%s&language=%s&paste=", key, description, language); char *encoded = url_encode(contents); snprintf(buf, sizeof(buf), "POST /api HTTP/1.1\r\nHost: paste.ee\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %i\r\n\r\n", strlen(req) + strlen(encoded)); send(sockfd, buf, strlen(buf), 0); send(sockfd, req, strlen(req), 0); send(sockfd, encoded, strlen(encoded), 0); snprintf(buf, sizeof(buf), "\r\n"); send(sockfd, buf, strlen(buf), 0); free(description); free(encoded); char resp[512]; memset(resp, 0, sizeof(resp)); recv(sockfd, resp, sizeof(resp), 0); close(sockfd); char delim[] = "\r\n"; char *ret = NULL; char *res = strtok(resp, delim); while(res != NULL) { if(strncmp(res, HTTP_PREFIX, strlen(HTTP_PREFIX)) == 0) { ret = malloc(sizeof(char) * (strlen(res) + 1)); memcpy(ret, res, strlen(res) + 1); break; } res = strtok( NULL, delim ); } return ret; } /* Converts an integer value to its hex character*/ char to_hex(char code) { static char hex[] = "0123456789abcdef"; return hex[code & 15]; } /* Returns a url-encoded version of str */ /* IMPORTANT: be sure to free() the returned string after use */ char *url_encode(char *str) { char *pstr = str, *buf = malloc(strlen(str) * 3 + 1), *pbuf = buf; while (*pstr) { if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') *pbuf++ = *pstr; else if (*pstr == ' ') *pbuf++ = '+'; else *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15); pstr++; } *pbuf = '\0'; return buf; }