#include #include // for tmstruct #include "libsockets.h" #include "libkeef.h" #if defined (UNIX) #include // for signal() #include // for SIGBUS, etc. #include #include #else if defined(WIN32) // Windows #include // for closesocket() #include // for _getcwd() #include // for getpid() #define sleep(SECS) Sleep(SECS*1000) #define close(SOCKET) closesocket(SOCKET) #define read(SOCKET,BUF,LEN) recv(SOCKET,BUF,LEN,/*flags=*/0) #define write(SOCKET,BUF,LEN) send(SOCKET,BUF,LEN,/*flags=*/0) #endif #include // for time(), strftime(), etc. /*glob*/int g_fDebug = 0; static char* g_pszOutfile = NULL; static char* g_pszErrfile = NULL; enum { iOK = 1, iERR = 2 }; #define ErrorLog printf #define DebugLog if (g_fDebug) printf #define MAXLEN_HOSTNAME 200 #ifndef PATH_SLASH #ifdef UNIX #define PATH_SLASH '/' #else #define PATH_SLASH '\\' #endif #endif #ifndef TXTNL #define TXTNL "\r\n" #endif //----------------------------------------------------------------------------- static char *g_Synopsis[] = { //----------------------------------------------------------------------------- " ", "httpget, (c) Copyright 1999 Ridgeware, Inc.", " ", "usage: httpget [-v] ", " ", "where:", " -v : verbosity for low level sockets debugging", " httpget.ini : infile contains a list of hostnames", " httpget.out : gets appended with timestamped data", " httpget.err : gets appended with timestamped error data", " ", "History:", " 03 Aug 99 : keef started", " ", NULL }; //----------------------------------------------------------------------------- static void NormalExit () //----------------------------------------------------------------------------- { DebugLog ("httpget: exiting normally\n"); #ifdef WIN32 WSACleanup(); #endif exit (0); } // NormalExit //----------------------------------------------------------------------------- static void ErrorExit (int iErrorValue) //----------------------------------------------------------------------------- { ErrorLog (" |\n"); ErrorLog (" \\ | | | /\n"); ErrorLog (" -- CRASHED --\n"); ErrorLog (" / | | | \\\n"); ErrorLog (" |\n"); #ifdef WIN32 WSACleanup(); #endif exit (iErrorValue); } // ErrorExit //----------------------------------------------------------------------------- static void SynopsisAndExit () //----------------------------------------------------------------------------- { for (int ii=0; g_Synopsis[ii]; ++ii) { printf ("%s\n", g_Synopsis[ii]); } NormalExit(); } // SynopsisAndExit //----------------------------------------------------------------------------- static BOOL ValidateHost (struct sockaddr_in* pAddrServer, char* pszHostname, char* szCanonical) //----------------------------------------------------------------------------- { memset ((void *)pAddrServer, 0, sizeof(struct sockaddr_in)); pAddrServer->sin_family = AF_INET; //pAddrServer->sin_port = htons(iPortNum); // - - - - - - - - - - - - - - - - - - - - - - // look at first char to determine if hostname or IP address: // - - - - - - - - - - - - - - - - - - - - - - if ((pszHostname[0] >= '0') && (pszHostname[0] <= '9')) { u_long ulAddress = inet_addr (pszHostname); if ((int)ulAddress == -1) { ErrorLog ("invalid hostname IP address '%s'\n", pszHostname); return (FALSE); } #if defined(hp) || defined(aix) || defined(bsd) pAddrServer->sin_addr.s_addr = ulAddress; //see: /usr/include/netinet/in.h, line 99 #else pAddrServer->sin_addr.S_un.S_addr = ulAddress; //see: /usr/include/netinet/in.h, line 118 #endif // see if we can translate the IP address into canonical hostname... struct hostent* pHost = gethostbyaddr ((char*)&ulAddress, sizeof(ulAddress), AF_INET); if (pHost) { strncpy (szCanonical, pHost->h_name, MAXLEN_HOSTNAME); szCanonical[MAXLEN_HOSTNAME] = 0; } } // - - - - - - - - - - - - - - - - - - - - - - // resolve hostname into an IP address: // - - - - - - - - - - - - - - - - - - - - - - else { struct hostent* pHost = gethostbyname (pszHostname); if (!pHost) { ErrorLog ("could not resolve hostname '%s' into an IP address\n", pszHostname); return (FALSE); } memcpy (&(pAddrServer->sin_addr), pHost->h_addr_list[0], sizeof(pAddrServer->sin_addr)); u_long ulAddress; #if defined(hp) || defined(aix) || defined(bsd) ulAddress = pAddrServer->sin_addr.s_addr; #else ulAddress = pAddrServer->sin_addr.S_un.S_addr; #endif strncpy (szCanonical, pHost->h_name, MAXLEN_HOSTNAME); szCanonical[MAXLEN_HOSTNAME] = 0; } return (TRUE); } // ValidateHost //----------------------------------------------------------------------------- static int SendCommand (struct sockaddr_in* pAddrServer, char* pszHostname, char* pszCommand) //----------------------------------------------------------------------------- // Don't send the EOBATCH { int fdSocket; DebugLog ("SendCommand(): opening new socket to daemon...\n"); if ((fdSocket = socket (AF_INET, SOCK_STREAM, 0)) < 0) { ErrorLog ("Can't open stream socket\n"); return (-1); // error } DebugLog ("SendCommand(): new fdSocket = %d, now trying a connect...\n", fdSocket); #ifdef UNIX // sanity check: 0=stdin, 1=stdout, 2=stderr, we should always be getting --> 3 <-- if (fdSocket != 3) { DebugLog ("SendCommand(): UNEXPECTED SOCKET NUMBER --> %d <--\n", fdSocket); DebugLog ("SendCommand(): 0=stdin, 1=stdout, 2=stderr, shouldn't we get 3 ???\n"); } #endif if (connect (fdSocket, (struct sockaddr *) pAddrServer, sizeof(struct sockaddr_in)) < 0) { DebugLog ("SendCommand(): connect returned and ERROR (errno=%d)\n", errno); ErrorLog ("Hostname '%s' is not reachable (errno=%d)\n", pszHostname, errno); TranslateErrno (); } DebugLog ("SendCommand(): connect happened, let's keep going...\n"); DebugLog ("SendCommand(): calling SocketWrite() to fdSocket = %d\n", fdSocket); SocketWrite (fdSocket, pszCommand); DebugLog ("SendCommand(): sent '%s'\n", pszCommand); return (fdSocket); } // SendCommand //----------------------------------------------------------------------------- void Output0 (int iWhich, char* pszHostname, char* pszString) //----------------------------------------------------------------------------- { static char szTime[50]; time_t longtime; struct tm* tmStruct; longtime = time (NULL); tmStruct = localtime (&longtime); strftime (szTime, 100, "%Y-%m-%d %H:%M:%S %a", tmStruct); if (iWhich == iERR) { FILE* fp1 = fopen (g_pszErrfile, "a"); if (!fp1) { printf ("httpget: cannot write to file '%s'.\n", g_pszErrfile); } else { fprintf (fp1, "ERR | %s | %s | %s\n", szTime, pszHostname, pszString); fclose (fp1); } } FILE* fp2 = fopen (g_pszOutfile, "a"); if (!fp2) { printf ("httpget: cannot write to file '%s'.\n", g_pszOutfile); } else { fprintf (fp2, "%s | %s | %s | %s\n", (iWhich==iERR)?"ERR":"OK ", szTime, pszHostname, pszString); fclose (fp2); } } // Output0 //----------------------------------------------------------------------------- void Output1s (int iWhich, char* pszHostname, char* pszFormat, char* sArg) //----------------------------------------------------------------------------- { static char szBuf[500]; sprintf (szBuf, pszFormat, sArg); Output0 (iWhich, pszHostname, szBuf); } // Output1s //----------------------------------------------------------------------------- void Output1d (int iWhich, char* pszHostname, char* pszFormat, int iArg) //----------------------------------------------------------------------------- { static char szBuf[500]; sprintf (szBuf, pszFormat, iArg); Output0 (iWhich, pszHostname, szBuf); } // Output1d //----------------------------------------------------------------------------- void ProcessHost (char* pszHostname, int iPortNum, char* pszURL) //----------------------------------------------------------------------------- { struct sockaddr_in AddrServer; char szCanonical[MAXLEN_HOSTNAME+1]; if (!ValidateHost (&AddrServer, pszHostname, szCanonical)) { Output1s (iERR, pszHostname, "could not resolve '%s' into IP address.", pszHostname); return; } AddrServer.sin_port = htons(iPortNum); char szCommand[500+1]; sprintf (szCommand, "GET %s HTTP/1.0\n\n", pszURL); int fdSocket = SendCommand (&AddrServer, szCanonical, szCommand); if (fdSocket <= 0) { Output1d (iERR, pszHostname, "attempt to write on socket resulted in errno=%d", errno); return; } #define MAXLEN_PROTOCOL 30 #define MAXLEN_BUFFER 100 #define MAXLEN_SERVER 100 char szProtocol[MAXLEN_PROTOCOL+1]; static char szLine[MAXLEN_BUFFER+1]; char szServer[MAXLEN_SERVER+1]; // HTTP/1.1 200 OK if (!SocketReadLine (fdSocket, szProtocol, MAXLEN_PROTOCOL)) { Output0 (iERR, pszHostname, "got nothing back after GET command"); return; } szProtocol[MAXLEN_PROTOCOL] = 0; // Server: Netscape-Enterprise/3.6 SP1 if (!SocketReadLine (fdSocket, szProtocol, MAXLEN_BUFFER)) { Output0 (iERR, pszHostname, "got nothing back after 1st line of header"); return; } strncpy (szServer, szLine+strlen("Server: "), MAXLEN_SERVER); szServer[MAXLEN_SERVER] = 0; close (fdSocket); static char szBuf[200+1]; sprintf (szBuf, "IP=%d.%d.%d.%d,P=%s,S=%s", InAddrB1 (AddrServer.sin_addr.s_addr), InAddrB2 (AddrServer.sin_addr.s_addr), InAddrB3 (AddrServer.sin_addr.s_addr), InAddrB4 (AddrServer.sin_addr.s_addr), szProtocol, szServer); Output0 (iOK, pszHostname, szBuf); return; } // ProcessHost //------------------------------------------------------------------------------ main (int argc, char* argv[]) //------------------------------------------------------------------------------ { char* pszInfile = NULL; char* pszSleep = NULL; char** pArgArray[] = {&pszSleep, NULL}; int iThisArg = 0; int iMaxArgs = 1; pszInfile = "httpget.ini"; g_pszOutfile = "httpget.out"; g_pszErrfile = "httpget.err"; for (int ii=1; ii= iMaxArgs) { printf ("httpget: argument '%s' not understood.\n", argv[ii]); SynopsisAndExit(); } *(pArgArray[iThisArg]) = argv[ii]; ++iThisArg; } } // check required args: if (!pszSleep) SynopsisAndExit (); #ifdef WIN32 WORD wVersionRequested = MAKEWORD(1,1); WSADATA wsaData; if (WSAStartup (wVersionRequested, &wsaData)) { ErrorLog ("main(): could not find a compatible WINSOCK DLL\n"); ErrorExit (-1); } #endif struct sockaddr_in AddrServer; char szHostname[MAXLEN_HOSTNAME+1]; char szCanonical[MAXLEN_HOSTNAME+1]; int iPortNum = 80; int iSleep = atoi(pszSleep); while (TRUE) { FILE* fpIn = fopen (pszInfile,"r"); if (!fpIn) { printf ("httpget: could not open infile '%s'\n.", pszInfile); } else { printf ("top of the batting order...\n"); while (fgets (szHostname, MAXLEN_HOSTNAME, fpIn)) { szHostname[strlen(szHostname)-1] = 0; ProcessHost (szHostname, 80, "/"); } fclose (fpIn); } printf ("sleeping %d secs...\n", iSleep); sleep (iSleep); } return (0); } // main - httpget