source view

Viewing finger.cpp

// finger.cpp : Defines the entry point for the console application.
//

#include <stdio.h>
#include <stdlib.h> // for exit()
#include <string.h> // for strchr(), strcpy()

#include <winsock2.h>

// fingers the user at the host
int finger(const char *user, const char *host);

// splits the string userhost into user and host
int parsehost(char *userhost, char **user, char **host);

int main(int argc, char* argv[])
{
// check we have correct number of command line arguments
if (argc != 2)
{
printf("\nusage: finger user@host\n");
return 0;
}

// start winsock
WSADATA wsData;
if (WSAStartup(WINSOCK_VERSION, &wsData) != 0)
{
printf("\nError starting winsock, exiting...\n");
exit(1);
}

// parse the string given on command line to make sure it's in correct format and to
// separate the user from the hostname.

char userhost[128] = { 0 };
char *user = NULL;
char *host = NULL;

strcpy(userhost, argv[1]);

if (parsehost(userhost, &user, &host) == 0)
{
finger(user, host); // finger it
}

// shutdown winsock
if(WSACleanup() == SOCKET_ERROR)
{
printf("\nError shutting down winsock, exiting...\n");
exit (1);
}

return 0;
}

int parsehost(char *userhost, char **user, char **host)
{
*user = userhost;

*host = strchr(userhost, '@'); // search for separator of name/host
if (*host == NULL)
{
printf("\nAdddress to finger must be in the form of user@host\n");
return 1;
}

**host = '\0'; // replace @ with end of string null
(*host)++; // advance pointer past new null to start of hostname

printf("User: %s\n", *user);
printf("Host: %s\n\n", *host);

return 0;
}

int finger(const char *user, const char *host)
{
// resolve hostname to address
hostent *phe;

phe = gethostbyname(host);
if (phe == NULL)
{
printf("Unable to resolve host\n\n");
return 1;
}

printf("Hostname: %s\n", phe->h_name);
printf("IP address: %s\n", inet_ntoa(*(in_addr*)phe->h_addr_list[0]));

// create TCP socket
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET)
{
printf("Failed to create TCP/IP socket\n\n");
return 1;
}

sockaddr_in sin;
memset(&sin, 0, sizeof(sockaddr_in));

sin.sin_family = AF_INET;
sin.sin_port = htons(79); // 79 == finger port
sin.sin_addr = *(in_addr *)phe->h_addr_list[0];

int status = connect(s, (sockaddr *)&sin, sizeof(sockaddr_in));
if (status == SOCKET_ERROR)
{
closesocket(s);
printf("Error connecting socket\n\n");
return 1;
}

// send username followed by \r\n
printf("Sending username: %s\r\n", user);

status = send(s, user, strlen(user), 0);
if (status == SOCKET_ERROR)
{
closesocket(s);
printf("Failure to send username\n\n");
return 1;
}

status = send(s, "\r\n", 2, 0);
if (status == SOCKET_ERROR)
{
closesocket(s);
printf("Failure to send username\n\n");
return 1;
}

int recv_result;
int totalbytes = 0;
char recvbuf[513] = { 0 };
while ((recv_result = recv(s, recvbuf, 512, 0)) > 0)
{
totalbytes += recv_result;
recvbuf[recv_result] = 0;
printf("%s", recvbuf); // print out data
}

// other end of connection closed socket
if (recv_result == 0)
{
printf("\nAll done, received %d bytes\n\n", totalbytes);
}
else
{
closesocket(s);
printf("Failure receiving data\n\n");
return 1;
}

closesocket(s);

return 0;
}