/* * httpPost * post a file via http * Copyright (c) 2003, 2004 by Hiroshi Tsujimura (tsupo@na.rim.or.jp) * All Right Reserved. * * 02 Nov 2003 * Last update: 26 Feb 2004 * * History: * $Log: RCS/httpPost.cv $ * Revision 1.1 2003/11/02 15:04:46 tsupo * Initial revision * */ #include #include #include #ifdef UNIX #include #include #include #include #include #endif #ifdef WIN32 #include #include #include #endif #ifndef lint static char *rcs_id = "$Header: httpPost.cv 1.1 2003/11/02 15:04:46 tsupo Exp $"; #endif #ifndef NUL #define NUL '\0' #endif #ifndef WIN32 #ifndef BOOL #define BOOL int #endif #endif #define DEFAULT_HTTP_PORT 80 #define MAX_SERVERNAME 512 #define SND_BUFFER_SIZE 10240 #define RCV_BUFFER_SIZE 65536 struct sockaddr_in saddrHTTPremote; /* sockaddr structure for httpd */ DWORD scdHTTP = (DWORD)-1; /* socket descriptor for httpd */ static char sndHTTP[SND_BUFFER_SIZE]; static char rcvHTTP[RCV_BUFFER_SIZE + 1]; int rcvHTTPbufferSize = RCV_BUFFER_SIZE; int sndHTTPmessageSize = 0; int rcvHTTPmessageSize = 0; int timeSpan = 0; char proxyServer[MAX_SERVERNAME]; unsigned short proxyPort = 0; BOOL useProxy = FALSE; BOOL verbose = FALSE; /* if TRUE, enabled verbose mode */ #ifdef DEBUG BOOL dump = FALSE; /* if TRUE, dump received data */ #endif #ifdef WIN32 int initSocket() { WORD wVersionRequested; /* Winsock version */ WSADATA sockInfo; /* Winsock information structure */ int ret; /* initialize for Winsock (requested Version 2.0) */ wVersionRequested = MAKEWORD( 2, 0 ); ret = WSAStartup( wVersionRequested, &sockInfo ); if ( ret == SOCKET_ERROR ) { /* if not found dll as Winsock 2.0, request Winsock 1.1 */ /* initialize for Winsock (requested Version 1.1) */ wVersionRequested = MAKEWORD( 1, 1 ); ret = WSAStartup( wVersionRequested, &sockInfo ); #if 0 if ( ret == SOCKET_ERROR ) return ( ret ); #endif } if ( verbose ) { if ( ret != SOCKET_ERROR ) { fprintf( stderr, "\n\tWinsock Version %d.%d\n", LOBYTE( sockInfo.wVersion ), HIBYTE( sockInfo.wVersion ) ); } } return ( ret ); } #endif /* WIN32 */ /* * connectHTTP() --- connect to httpd process on web/proxy server * argument: web server name (or IP address) * return: if connect OK, returns 0; else returns non 0 value */ int connectHTTP( const char *webServer, int *flag ) { int ret = 1, retryCnt = 0; long len; struct protoent *p, pe; struct servent *q, se; struct hostent *rp, rh; unsigned long inaddrRemote; unsigned short port = 0; char *server; #ifdef WIN32 if ( initSocket() == SOCKET_ERROR ) return ( ret ); #endif if ( useProxy ) { server = proxyServer; port = htons( proxyPort ); } else { char *s = webServer; if ( (s = strchr( webServer, ':' )) != NULL ) { /* In case of 'http://server:port/' */ *s++ = NUL; if ( (*s >= '0') && (*s <= '9') ) { port = atol( s ) & 0xFFFF; port = htons( port ); } } server = webServer; } /* * create a socket */ p = getprotobyname( "tcp" ); memcpy( (char *)&pe, (char *)p, sizeof ( struct protoent ) ); p = &pe; scdHTTP = socket( PF_INET, SOCK_STREAM, p->p_proto ); if ( (long)scdHTTP < 0 ) return ( ret ); #ifdef WIN32 if ( scdHTTP == INVALID_SOCKET ) return ( ret ); #endif /* * set a port */ if ( port == 0 ) { q = getservbyname( "http", "tcp" ); if ( !q ) { /* fprintf( stderr, "\tgetservbyname(): failed.\n" ); */ if ( verbose ) fprintf( stderr, "\texpected http port is %d\n", DEFAULT_HTTP_PORT ); port = htons( DEFAULT_HTTP_PORT ); } else { memcpy( (char *)&se, (char *)q, sizeof ( struct servent ) ); q = &se; port = q->s_port; if ( verbose ) { fprintf( stderr, "\tprotocol #%d, port #%d\n", p->p_proto, ntohs( q->s_port ) ); } } } rp = gethostbyname( server ); if ( !rp ) { if ( (server[0] >= '0') && (server[0] <= '9') && (strchr( server, '.' ) != NULL) ) { char *p, *q, *r, *s; p = server; q = strchr( server, '.' ); if ( !q ) return ( ret ); r = strchr( q + 1, '.' ); if ( !r ) return ( ret ); s = strchr( r + 1, '.' ); if ( !s ) return ( ret ); q++, r++, s++; if ( (*p < '0') || (*p > '9') || (*q < '0') || (*q > '9') || (*r < '0') || (*r > '9') || (*s < '0') || (*s > '9') ) return ( ret ); saddrHTTPremote.sin_addr.s_addr = ((atol( p ) & 0xFF) << 24) | ((atol( q ) & 0xFF) << 16) | ((atol( r ) & 0xFF) << 8) | (atol( s ) & 0xFF); #ifndef SUNOS saddrHTTPremote.sin_addr.s_addr = htonl( saddrHTTPremote.sin_addr.s_addr ); #endif if ( verbose ) { fprintf( stderr, "\tremote address = %d:%d:%d:%d\n", atol( p ) & 0xff, atol( q ) & 0xff, atol( r ) & 0xff, atol( s ) & 0xff ); } } else { fprintf( stderr, "\t%s: not found.\n", server ); return ( ret ); } } else { memcpy( &rh, rp, sizeof (struct hostent) ); rp = &rh; if ( verbose ) { fprintf( stderr, "\tremote name = %s\n", rp->h_name ); fprintf( stderr, "\tremote address = %d:%d:%d:%d\n", (rp->h_addr[0]) & 0xff, (rp->h_addr[1]) & 0xff, (rp->h_addr[2]) & 0xff, (rp->h_addr[3]) & 0xff ); } if ( strcmp( webServer, rp->h_name ) != 0 ) *flag = FALSE; else if ( strstr( webServer, "bulknews" ) != NULL ) *flag = FALSE; else *flag = TRUE; #ifdef SUNOS saddrHTTPremote.sin_addr.s_addr = ((rp->h_addr[0] & 0xFF) << 24) | ((rp->h_addr[1] & 0xFF) << 16) | ((rp->h_addr[2] & 0xFF) << 8) | (rp->h_addr[3] & 0xFF); #else if ( !(rp->h_addr_list) || !(rp->h_addr_list[0]) ) { return ( ret ); } inaddrRemote = *(unsigned long *)(rp->h_addr_list[0]); saddrHTTPremote.sin_addr = *(struct in_addr *)&inaddrRemote; memset( saddrHTTPremote.sin_zero, 0x00, 8 ); #endif } saddrHTTPremote.sin_family = AF_INET; saddrHTTPremote.sin_port = port; len = sizeof (struct sockaddr_in); /* * connect to web server (or proxy server) */ if ( verbose ) fprintf( stderr, "\tConnecting to HTTP server on %s...", server ); do { ret = connect( scdHTTP, (struct sockaddr *)&saddrHTTPremote, len ); if ( ret < 0 ) { #ifdef WIN32 putchar( '.' ); #else perror( "\nconnect" ); #endif retryCnt++; close( scdHTTP ); scdHTTP = -1; if ( retryCnt < 5 ) { sleep( 10 ); scdHTTP = socket( PF_INET, SOCK_STREAM, p->p_proto ); if ( (long)scdHTTP < 0 ) return ( ret ); #ifdef WIN32 if ( scdHTTP == INVALID_SOCKET ) { return ( ret ); } #endif } else { #ifdef WIN32 WSACleanup(); putchar( '\n' ); #endif goto EXIT; } } } while ( ret < 0 ); ret = 0; EXIT: return ( ret ); } /* * disconnectHTTP() --- disconnect from httpd process on web/proxy server * arguments: none * return: none (void) */ void disconnectHTTP() { close( scdHTTP ); scdHTTP = -1; #ifdef WIN32 WSACleanup(); #endif if ( verbose ) fprintf( stderr, "\n\tConnection closed\n" ); } /* * sendHTTP() --- send a HTTP/POST request to httpd process * argument: none * return: if send OK, returns 0; else returns non 0 value * (if detected disconnection, returns -2) */ int sendHTTP() { int ret = 1; /* * send a request via socket */ ret = send(scdHTTP, sndHTTP, sndHTTPmessageSize, 0); if ( ret <= 0 ) { #ifdef WIN32 if ( h_errno == WSAECONNRESET ) { fprintf( stderr, "\n\tConnection is lost.\n" ); return ( -2 ); } #else perror( "send" ); #endif return ( -1 ); } #ifdef DEBUG fprintf( stderr, "send %dbytes to HTTP server\n", ret ); #endif return ( 0 ); } /* * recvHTTP() --- receive a responce from httpd process * argument: none * return: byte length of received data * if receive OK, then returns received-data-length; * else returns negative integer value * (if detected disconnection, returns -2) */ int timedout = 0; int timedoutTime = 60; int recvHTTP() { int ret = 1; fd_set rfds[1]; struct timeval t; FD_ZERO( rfds ); t.tv_sec = timedoutTime; t.tv_usec = 0; timedout = 0; /* * receive data via socket */ rcvHTTPbufferSize = RCV_BUFFER_SIZE; memset( rcvHTTP, 0, rcvHTTPbufferSize ); FD_SET( scdHTTP, rfds ); ret = select( FD_SETSIZE, rfds, NULL, NULL, &t ); FD_CLR( scdHTTP, rfds ); if ( ret <= 0 ) { fputs( "\trecv: timed out\n", stderr ); timedout = 1; return ( -1 ); } ret = recv( scdHTTP, rcvHTTP, rcvHTTPbufferSize, 0 ); if( ret < 0 ) { #ifdef WIN32 if ( h_errno == WSAECONNRESET ) { fprintf( stderr, "\n\tConnection is lost.\n" ); return ( -2 ); } #else perror( "recv" ); #endif return ( -1 ); } rcvHTTPmessageSize = ret; #ifdef DEBUG fprintf( stderr, "\treceived %dbytes from HTTP server\n", ret ); #endif if ( ret == 0 ) { if ( verbose ) fprintf( stderr, "\tConnection closed by server.\n" ); return ( -2 ); } #ifdef DEBUG if ( dump ) { int i, c; unsigned char buf[80]; for ( i = 0; i < ret; i++ ) { if ( (i != 0) && (i % 16 == 0) ) { buf[16] = NUL; fprintf( stderr, " %s\n", buf ); } if ( i % 16 == 0 ) fprintf( stderr, "%08x:", &rcvHTTP[i] ); c = rcvHTTP[i] & 0xFF; if ( (c >= ' ') && (c <= 0x7E) ) buf[i % 16] = c; else buf[i % 16] = '.'; fprintf( stderr, " %02x", c & 0xFF ); } if ( i % 16 == 0 ) buf[16] = NUL; else { buf[i % 16] = NUL; for ( i = i % 16; i < 16; i++ ) fputs( " ", stderr ); } fprintf( stderr, " %s\n", buf ); } #endif return ( 0 ); } /* * _httpPost() --- post a XML-RPC request via httpd process * arguments: * char *webServer; web server which has target web page * char *webPage; target web page * return: if get OK, returns 0; else returns non 0 value * (if detected disconnection before receiving target web page, * returns -2) */ int _httpPost( const char *webServer, const char *webPage, int flag, const char *sndBody ) { int ret; int count = 0; char *p, *q; size_t sndLength = strlen( sndBody ); if ( useProxy ) { if ( (webPage[0] == NUL) || !strcmp( webPage, "/" ) ) sprintf( sndHTTP, "POST http://%s/", webServer ); else sprintf( sndHTTP, "POST http://%s%s", webServer, webPage ); } /* else if ( flag == FALSE ) */ sprintf( sndHTTP, "POST http://%s%s", webServer, webPage ); /* else sprintf( sndHTTP, "POST %s", webPage ); */ strcat( sndHTTP, " HTTP/1.0\n" ); strcat( sndHTTP, "Accept: */*\n" ); strcat( sndHTTP, "User-Agent: httpPost/1.0 (written by H.Tsujimura)\n"); sprintf( &sndHTTP[strlen(sndHTTP)], "Host: %s\n", webServer ); strcat( sndHTTP, "Content-Type: text/xml\n" ); sprintf( &sndHTTP[strlen(sndHTTP)], "Content-Length: %d\n\n", sndLength ); strcat( sndHTTP, sndBody ); if ( verbose ) fprintf( stderr, "\t%s\n", sndHTTP ); sndHTTPmessageSize = strlen( sndHTTP ); ret = sendHTTP(); if ( !ret ) { do { ret = recvHTTP(); if ( rcvHTTPmessageSize > 0 ) { p = rcvHTTP; if ( count == 0 ) { if ( *p != '<' ) { if ( ( q = strchr( p, '<' ) ) != NULL ) p = q; else continue; } } fputs( p, stdout ); } count++; #ifdef DEBUG fprintf( stderr, "\tcount = %d\n", count ); #endif } while ( !ret ); } else { fprintf( stderr, "\tsendHTTP(): failed\n" ); } return ( ret ); } /* * httpPost() --- post a weblogupdate ping * arguments: * FILE *output; stream for writing as target web page * char *webServer; web server which has target web page * char *webPage; target web page * return: if get OK, returns TRUE; else returns FALSE */ BOOL httpPost( FILE *output, const char *webServer, const char *webPage, const char *weblogName, const char *weblogURL ) { DWORD dwSize = 0; char *szBuf = NULL; int ret = FALSE; int flag = TRUE; char buffer[BUFSIZ]; sprintf( buffer, "\n" "\nweblogUpdates.ping\n" "\n\n%s\n\n" "\n%s\n\n\n" "\n\n", weblogName, weblogURL ); if ( !connectHTTP( webServer, &flag ) ) { if ( verbose ) fprintf( stderr, "\tconnected!\n" ); _httpPost( webServer, webPage, flag, buffer ); disconnectHTTP(); ret = TRUE; } else fprintf( stderr, "\tconnect failed!\n" ); return ret; } void getProxyInfo( int *useProxy, char *proxyServer, unsigned short *proxyPort ) { FILE *fp; if ( ( fp = fopen( "proxy.txt", "r" ) ) != NULL ) { char *p, *q; char buf[BUFSIZ]; while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) { if ( p[strlen(p) - 1] == '\n' ) p[strlen(p) - 1] = NUL; if ( ((q = strchr( p, '.' )) != NULL) || (*p < '0') || (*p > '9') ) { strcpy( proxyServer, p ); } else if ( (*p >= '0') && (*p <= '9') ) { *proxyPort = (atol( p ) & 0xFFFF); } } fclose( fp ); if ( (*proxyPort > 0) && (proxyServer[0] != NUL) ) { if ( verbose ) fprintf( stderr, "\tproxy = %s:%d\n", proxyServer, *proxyPort ); *useProxy = TRUE; } } #ifdef WIN32 if ( *useProxy == FALSE ) { /* get proxy information from Registory */ /* HKEY_CURRENT_USER */ /* Software\Microsoft\Windows\CurrentVersion\Internet Settings */ /* ProxyServer */ long ret; HKEY hk; long type; char buf[BUFSIZ], *p; long sz = BUFSIZ - 1; ret = RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 0, KEY_READ, &hk ); if ( ret == ERROR_SUCCESS ) { ret = RegQueryValueEx( hk, "ProxyServer", NULL, &type, buf, &sz ); if ( ret == ERROR_SUCCESS ) { if ( type == REG_SZ ) { p = strchr( buf, ':' ); if ( p ) { *p = '\0'; strcpy( proxyServer, buf ); *proxyPort = atol( p + 1 ); if ( (*proxyPort > 0) && (proxyServer[0] != NUL) ) { if ( verbose ) fprintf( stderr, "\tproxy = %s:%d\n", proxyServer, *proxyPort ); *useProxy = TRUE; } } } RegCloseKey( hk ); } } } #endif /* WIN32 */ } void getWeblogInformation( const char *filename, char *weblogName, char *weblogURL ) { FILE *fp; char *p, *q, buf[BUFSIZ]; if ( ( fp = fopen( filename, "r" ) ) != NULL ) { while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) { if ( !strncmp( p, "", 7 ) ) { q = strrchr( p + 7, '<' ); if ( q && *q ) *q = NUL; strcpy( weblogName, p + 7 ); continue; } if ( !strncmp( p, "<link>", 6 ) ) { q = strrchr( p + 6, '<' ); if ( q && *q ) *q = NUL; strcpy( weblogURL, p + 6 ); continue; } if ( !strncmp( p, "<items>", 7 ) ) break; } fclose( fp ); } if ( verbose ) fprintf( stderr, "url = %s\n", weblogURL ); } time_t timeValue( int yy, int mm, int dd, int HH, int MM, int SS ) { static int m[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; time_t t; if ( verbose ) fprintf( stderr, "target's timestamp: %04d-%02d-%02d %02d:%02d:%02d\n", yy, mm, dd, HH, MM, SS ); #define isLeapYear( y ) \ (((y) % 4) == 0) && ((((y) % 100) != 0) || (((y) % 400) == 0)) t = (((dd - 1) * 24 + HH) * 60 + MM) * 60 + SS; t -= 9 * 60 * 60; /* JST -> GMT */ while ( yy >= 1970 ) { while ( --mm >= 1 ) { if ( (mm == 2) && isLeapYear( yy ) ) t += (24 * 60 * 60); t += (m[mm - 1] * 24 * 60 * 60); } yy--; mm = 13; } #undef isLeapYear return ( t ); } int httpGet( const char *url ) { int flag = 0, ret = -1; char cmd[BUFSIZ], *p; FILE *fp; time_t t = time( NULL ), tt = 0; int yy, mm, dd, HH, MM, SS; int strncmpi( const char *, const char *, size_t ); sprintf( cmd, "httpRead%s%s > i.html", useProxy ? " -p " : " ", url ); if ( verbose ) fprintf( stderr, "\t%% %s\n", cmd ); system( cmd ); if ( ( fp = fopen( "i.html", "r" ) ) == NULL ) return ( ret ); while ( ( p = fgets( cmd, BUFSIZ - 1, fp ) ) != NULL ) { if ( (flag == 0) && !strncmpi( p, "<META NAME=\"WWWC\" CONTENT=\"", 27 ) ) { p += 27; *( p + 4 ) = '\0'; yy = atoi( p ); p += 5; *( p + 2 ) = '\0'; mm = atoi( p ); p += 3; *( p + 2 ) = '\0'; dd = atoi( p ); p += 3; *( p + 2 ) = '\0'; HH = atoi( p ); p += 3; *( p + 2 ) = '\0'; MM = atoi( p ); SS = 0; tt = timeValue( yy, mm, dd, HH, MM, SS ); break; } if ( (flag == 0) && !strncmp( p, "<rdf:Description", 16 ) ) flag++; else if ( flag == 1 ) { while ( (*p == ' ') || (*p == '\t') ) p++; if ( !strncmp( p, "dc:date=\"", 9 ) ) { p += 9; *( p + 4 ) = '\0'; yy = atoi( p ); p += 5; *( p + 2 ) = '\0'; mm = atoi( p ); p += 3; *( p + 2 ) = '\0'; dd = atoi( p ); p += 3; *( p + 2 ) = '\0'; HH = atoi( p ); p += 3; *( p + 2 ) = '\0'; MM = atoi( p ); p += 3; *( p + 2 ) = '\0'; SS = atoi( p ); tt = timeValue( yy, mm, dd, HH, MM, SS ); break; } } } fclose( fp ); unlink( "i.html" ); if ( t >= tt ) { int diff = (t - tt) / (60 * 60); if ( diff < timeSpan ) ret = diff; /* this web page is updated */ } if ( verbose ) if ( ret >= 0 ) fprintf( stderr, "timeDiff: %d (Hours)\n", ret ); return ( ret ); } /* * usage: * httpPost [-v] [-p] http://aaa.bbb/ccc weblogName http://weblog/url * httpPost [-v] [-p] http://aaa.bbb:port/ccc weblogName http://weblog/url * httpPost [-v] [-p] -f weblogDefinitionFile http://aaa.bbb:port/ccc * -v: verbose mode * -p: connect via proxy server * proxy server specified: * proxy.txt * proxyServerName * proxyPortNumber * -d: dump receive data buffer (for DEBUG use only) * -f: use RSS Feed as a definition file for target blog * 'weblogDefinitionFile': RSS file name (RSS 1.0, expected) * * httpPost [-v] [-p] -G time * http://aaa.bbb:port/ccc weblogName http://weblog/url * httpPost [-v] [-p] -G time * http://aaa.bbb:port/ccc weblogName http://weblog/url * httpPost [-v] [-p] -G time * -f weblogDefinitionFile http://aaa.bbb:port/ccc * -G: get html file, and research modified time. if modified time near * specified 'time', then send update ping. unless, not send. * */ int main( int argc, char *argv[] ) { char webServer[MAX_SERVERNAME]; char webPage[MAX_SERVERNAME]; char weblogName[BUFSIZ]; char weblogURL[MAX_SERVERNAME]; int argIndex = 1; int argRemain = argc; int i, j, flag = 0; proxyServer[0] = NUL; weblogName[0] = NUL; weblogURL[0] = NUL; for ( i = 1; i < argc; i++ ) { if ( argv[i][0] != '-' ) break; for ( j = 1; argv[i][j]; j++ ) { switch ( argv[i][j] ) { case 'v': verbose = !verbose; break; case 'p': useProxy = !useProxy; break; case 'f': { char *p = NULL; if ( argv[i][j + 1] != NUL ) { p = &argv[i][j + 1]; j = strlen( argv[i] ) - 1; } else if ( i < argc - 1 ) { p = argv[i + 1]; argRemain--; argIndex++; i++; flag = 1; } if ( p ) getWeblogInformation( p, weblogName, weblogURL ); } break; #ifdef DEBUG case 'd': dump = !dump; break; #endif case 'G': if ( argv[i][j + 1] ) { timeSpan = atoi( &(argv[i][j + 1]) ); j = strlen( argv[i] ) - 1; } else if ( i < argc - 1 ) { timeSpan = atoi( argv[i + 1] ); argRemain--; argIndex++; i++; flag = 1; } break; } if ( flag == 1 ) { flag = 0; break; } } argRemain--; argIndex++; } if ( argRemain > 1 ) { char *p = argv[argIndex], *q; char *hStr = "http://"; int len = strlen( hStr ); if ( !strncmp( p, hStr, len ) ) p += len; if ( argRemain >= 2 ) { if ( ( q = strchr( p, '/' ) ) != NULL ) { strncpy( webServer, p, q - p ); webServer[q - p] = NUL; strcpy( webPage, q ); } else { fprintf( stderr, "\t%s: invalid URL\n", argv[argIndex] ); return ( FALSE ); } if ( weblogName[0] == NUL ) { if ( argRemain > 2 ) { strcpy( weblogName, argv[argIndex + 1] ); if ( argRemain > 3 ) strcpy( weblogURL, argv[argIndex + 2] ); } } } if ( weblogName[0] == NUL ) { fprintf( stderr, "Not specified Weblog Name for update.\n" ); return ( FALSE ); } if ( weblogURL[0] == NUL ) { fprintf( stderr, "Not specified Weblog URL for update.\n" ); return ( FALSE ); } } else { fprintf( stderr, "Not specified target web page.\n" ); return ( FALSE ); } if ( useProxy ) { useProxy = FALSE; getProxyInfo( &useProxy, proxyServer, &proxyPort ); if ( useProxy == FALSE ) { fprintf( stderr, "\tNot specified proxy server\n" ); return ( FALSE ); } } if ( timeSpan > 0 ) { int ret = httpGet( weblogURL ); if ( (ret <= 0) || (ret > timeSpan) ) return ( 0 ); } return ( httpPost( stdout, webServer, webPage, weblogName, weblogURL ) ); } /* * How to compile on UNIX: * cc -o httpPost httpPost.c * * How to build 'httpRead.exe' with LCC-WIN32: * lcc -c -O httpPost.c * lcclnk -o httpPost.exe httpPost.obj ws2_32.lib */