Resolve TinyURLs

This will take tinyurls and output the real address of the location they point to.

#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#endif
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
using namespace std;

int main(int argc, char ** argv) {
	if (argc != 2) {
		cout <<
			"URL Lengthener by Jakash3\n"
			"Usage: " << argv[0] << " URL\n";
		return 1;
	}
	int i;
	string url(argv[1]);
	char buf[512];
	struct addrinfo hints, *ai;
#ifdef _WIN32
	SOCKET sock;
	
	struct WSAData * wd;
	wd = (struct WSAData*)malloc(sizeof(struct WSAData));
	if (WSAStartup(MAKEWORD(2, 0), wd)) {
		cout << "Failed to initialize winsock api." << endl;
		free(wd);
		return 1;
	}
	free(wd);
#else
	int sock;
#endif
	
	if (url.find("http://") == 0) url.erase(0, 7);
	url += " HTTP/1.1\r\nHost: ";
	url += url.substr(0, url.find('/')) += "\r\n\r\n";
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	if ((i = getaddrinfo(url.substr(0, url.find('/')).c_str(), "80", &hints, &ai))) {
		cout << gai_strerror(i) << endl;
		return 1;
	}
	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
	if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
		cout << "Failed to connect." << endl;
		return 1;
	}
	freeaddrinfo(ai);
	url.insert(url.find('/'), "GET ");
	url.erase(0, url.find("GET "));
	send(sock, url.c_str(), url.size(), 0);
	for (;;) {
		for (i = 0; ; i++) {
			recv(sock, &(buf[i]), 1, 0);
			if (i >= 1);
			if (buf[i] == '\n' && buf[i - 1] == '\r') break;
		}
		buf[++i] = 0;
		if (!strcmp(buf, "\r\n")) {
			cout << "Host is not a url shortening service." << endl;
#ifdef _WIN32
			closesocket(sock);
			WSACleanup();
#else
			close(sock);
#endif
			return 1;
		}	
		if (!strncmp(buf, "Location: ", 10)) break;
	}
	*(strchr(buf, '\r')) == 0;
	memmove(buf, buf + 10, strlen(buf + 10) + 1);
	cout << buf << endl;
#ifdef _WIN32
	closesocket(sock);
	WSACleanup();
#else
	close(sock);
#endif
	return 0;
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: