123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#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;
}