/******************************************************************************* * rfaxping.cpp * Connect to a RightFax server and display the server information. * * Compile: * CL -I "-DVERS=\"R.L\"" rfaxping.cpp rfaxprogram.obj \rfwin32.lib * where * 'R.L' is the program version number; * '' is the directory containing "rfapi.h" and "rfwin32.lib". * *------------------------------------------------------------------------------- * @version $Revision: 1.1 $ $Date: 2008/04/03 22:05:05 $ * @since 2008-04-03 * @author David R. Tribble (david@tribble.com) * * Copyright ©2008 by David R. Tribble, all rights reserved. * Permission is granted to any person or entity except those designated * by the United States Department of State as a terrorist, or terrorist * government or agency, to use and distribute this source code provided * that the original copyright notice remains present and unaltered. */ // Identification static char REV[] = "@(#)drt/rightfax/src/rfaxping.cpp $Revision: 1.1 $ $Date: 2008/04/03 22:05:05 $"; static char PROG[] = "rfaxping"; static char TITLE[] = "RFaxPing - Test a network connection to a RightFax server"; #ifndef VERS #error Please define macro "VERS" as a string in the format "R.L" #endif static char VERSION[] = VERS; static char VERSION_W[] = "@(#)" "Release: " VERS; static char BUILT[] = "@(#)" "Built: " __DATE__; // System includes #ifndef _WIN32 #error Compile this file for Win32 only #endif #include #include #include #include #include #include #define WIN32 #define WIN32_LEAN_AND_MEAN 1 #include #include // Local includes #define rfaxprogram_cpp #include "rfaxprogram.hpp" //------------------------------------------------------------------------------ // Local classes //------------------------------------------------------------------------------ /******************************************************************************* * class RFaxPinger * Connect to a RightFax server and display the server information. * * @since 1.1, 2008-04-03 */ #define RFaxPinger_VS 100 // Class version, 1.0 class RFaxPinger: public RFaxProgram { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Constants public: // Program exit status enum ExitCode { RC_OKAY = 0, // Success RC_CONNECT = 1, // Can't connect to server RC_INFO = 2, // Can't retrieve server info RC_USAGE = 255, // Improper usage }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Static functions public: /*************************************************************************** * Connect to a RightFax server and display the server information. * * Usage * rfaxping [-s] host * *--------------------------------------------------------------------------- * @param argc * Argument count, i.e., the number of elements in 'argv[]'. * * @param argv * Command line arguments. * * @return * Exit status code, which is one of the RC_XXX constants. * * @since 1.1, 2008-04-03 */ static int main(int argc, const char *const *argv); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Functions public: /*************************************************************************** * Destructor. * * @since 1.1, 2008-04-03 */ virtual ~RFaxPinger(); /*************************************************************************** * Default constructor. * * @since 1.1, 2008-04-03 */ RFaxPinger(); /*************************************************************************** * Retrieve information about the fax server. * This updates the 'm_info' variable. * * @return * True if the server information was retrieved successfully, otherwise * false. * * @since 1.1, 2008-04-03 */ virtual bool getServerInfo(); /*************************************************************************** * Write the fax server information to an output file. * * @param out * Output stream. * * @since 1.1, 2008-04-03 */ void printServerInfo(FILE *out); private: // Not implemented RFaxPinger(const RFaxPinger &o); // Not implemented const RFaxPinger & operator =(const RFaxPinger &o); }; //------------------------------------------------------------------------------ // Class functions //------------------------------------------------------------------------------ /******************************************************************************* * RFaxPinger::main() * Connect to a RightFax server and display the server information. * * Usage * rfaxping [-s] host * *------------------------------------------------------------------------------- * @param argc * Argument count, i.e., the number of elements in 'argv[]'. * * @param argv * Command line arguments. * * @since 1.1, 2008-04-03 */ /*static*/ int RFaxPinger::main(int argc, const char *const *argv) { #if RFaxPinger_VS/100 != 1 #error class RFaxPinger has changed #endif const char * addr = NULL; RFaxPinger * srv; int i; int rc = RC_OKAY; // Parse command line options for (i = 1; i < argc and argv[i][0] == '-'; i++) { if (::stricmp(argv[i], "-?") == 0 or ::stricmp(argv[i], "/?") == 0 or ::stricmp(argv[i], "-help") == 0 or ::stricmp(argv[i], "/help") == 0) goto usage; else if (::strcmp(argv[i], "-s") == 0 and i+1 < argc) addr = argv[++i]; else goto usage; } // Parse command line arguments if (addr == NULL and i < argc) addr = argv[i++]; // Check command usage if (addr == NULL) goto usage; // Establish a connection to the RightFax server srv = new RFaxPinger(); ::printf("Server: %s\n", addr); ::fflush(stdout); if (not srv->connect(addr)) { delete srv; return RC_CONNECT; } // Retrieve information about the RightFax server ::printf("\n"); if (not srv->getServerInfo()) { ::printf("Can't retrieve server info: %s\n", addr); ::fflush(stdout); rc = RC_INFO; goto done; } // Display the server info srv->printServerInfo(stdout); ::printf("\n"); ::fflush(stdout); done: // Disconnect from server srv->disconnect(); delete srv; // Done return rc; usage: // Display program version banner ::printf("%s\n", TITLE); ::printf("Version %s [%s]\n", VERSION, BUILT+4); ::printf("\n"); ::printf("Test the connection to a RightFax server.\n"); ::printf("\n"); ::fflush(stdout); // Improper program usage ::printf("usage: %s [-s] host\n", PROG); ::printf("\n"); ::printf("'host' is a RightFax host name or IP address.\n"); ::fflush(stdout); return RC_USAGE; } /******************************************************************************* * RFaxPinger::~RFaxPinger() * Destructor. * * @since 1.1, 2008-04-03 */ /*virtual*/ RFaxPinger::~RFaxPinger() { #if RFaxPinger_VS != 100 #error class RFaxPinger has changed #endif // Deallocate } /******************************************************************************* * RFaxPinger::RFaxPinger() * Default constructor. * * @since 1.1, 2008-04-03 */ RFaxPinger::RFaxPinger(): RFaxProgram() { #if RFaxPinger_VS != 100 #error class RFaxPinger has changed #endif // Initialize members } /******************************************************************************* * RFaxPinger::getServerInfo() * Retrieve information about the fax server. * This updates the 'm_info' variable. * * @return * True if the server information was retrieved successfully, otherwise false. * * @since 1.1, 2008-04-03 */ /*virtual*/ bool RFaxPinger::getServerInfo() { #if RFaxPinger_VS/100 != 1 #error class RFaxPinger has changed #endif unsigned long t; char tbuf[20+1]; int tz; // Attempt to retrieve server info from the fax server if (not RFaxProgram::getServerInfo()) return false; // Display partial server info ::printf("Got RightFax server info: %s, %s\n", m_serverIP, m_server); ::printf("\n"); // Display partial server info t = m_info->ulBuildDate; ::sprintf(tbuf, "%02lX/%02lX/%04lX", t%0x10000/0x100, t%0x100, t/0x10000); ::printf("RightFax server: %lX.%02lX %s [%s]\n", m_info->ulServerVersion/0x100, m_info->ulServerVersion%0x100, tbuf, m_info->szSerialNumber); ::fflush(stdout); // Timezone offset has changed (DST has changed) tz = m_tz; tz = (tz < 0 ? -tz : tz); ::printf("Server TZ offset: UTC%c%02d:%02d\n", (m_tz < 0 ? '-' : '+'), tz/60/60, tz/60%60); ::fflush(stdout); // Success return true; } /******************************************************************************* * RFaxPinger::printServerInfo() * Write the fax server information to an output file. * * @param out * Output stream. * * @since 1.1, 2008-04-03 */ void RFaxPinger::printServerInfo(FILE *out) { #if RFaxPinger_VS/100 != 1 #error class RFaxPinger has changed #endif unsigned long t; char tbuf[20+1]; // Sanity check if (out == NULL) return; // Print server info ///::fprintf(out, "[SERVERINFO2]\n"); ::fprintf(out, "ServerType: %lu, %s\n", m_info->ulServerType, (m_info->ulServerType == SERVERTYPE_OS2 ? "OS/2" : m_info->ulServerType == SERVERTYPE_NT ? "NT" : "unknown")); ::fprintf(out, "ServerVersion: %04lX, %lX.%02lX\n", m_info->ulServerVersion, m_info->ulServerVersion/0x100, m_info->ulServerVersion%0x100); ::fprintf(out, "ServerSpecial: %lu\n", m_info->ulServerSpecial); ::fprintf(out, "ImageLocServer: '%.*s'\n", sizeof(m_info->szImageLocServer), m_info->szImageLocServer); ::fprintf(out, "ImageLocVolume: '%.*s'\n", sizeof(m_info->szImageLocVolume), m_info->szImageLocVolume); ::fprintf(out, "MaxUsers: %d%s\n", m_info->sMaxUsers, (m_info->sMaxUsers == 0 ? ", unlimited" : "")); ::fprintf(out, "VerifyCodes: %d\n", m_info->sVerifyCodes); ::fprintf(out, "BillDesc1: '%.*s'\n", sizeof(m_info->szBillDesc1), m_info->szBillDesc1); ::fprintf(out, "BillDesc2: '%.*s'\n", sizeof(m_info->szBillDesc2), m_info->szBillDesc2); // Skip: m_info->acReqFields t = m_info->ulBuildDate; ::sprintf(tbuf, "%02lX/%02lX/%04lX", t%0x10000/0x100, t%0x100, t/0x10000); ::fprintf(out, "BuildDate: %08lX, %s\n", m_info->ulBuildDate, tbuf); ::fprintf(out, "ImageDir: '%.*s'\n", sizeof(m_info->szImageDir), m_info->szImageDir); ::fprintf(out, "BaseRFDir: '%.*s'\n", sizeof(m_info->szBaseRFDir), m_info->szBaseRFDir); ::fprintf(out, "Flags: %04lX\n", m_info->ulFlags); // Skip: m_info->fEnterprise // Skip: m_info->fDocsOnDemand // Skip: m_info->fTeleconnect // Skip: m_info->fSatellite // Skip: m_info->fSBS ::fprintf(out, "TimeZoneInfo: "); t = m_info->TimeZoneInfo.Bias + m_info->TimeZoneInfo.StandardBias; ::fprintf(out, "%+03ld:%02ld", t/60, t%60); t = m_info->TimeZoneInfo.Bias + m_info->TimeZoneInfo.DaylightBias; ::fprintf(out, "/%+03ld:%02ld\n", t/60, t%60); ::fprintf(out, "TimeZoneInfoValid: %d\n", m_info->fTimeZoneInfoValid); ::fprintf(out, "ANSICP: '%.*s'\n", sizeof(m_info->szANSICP), m_info->szANSICP); ::fprintf(out, "OEMCP: '%.*s'\n", sizeof(m_info->szOEMCP), m_info->szOEMCP); // Skip: m_info->fProdEnabled // Skip: m_info->fProdINL // Skip: m_info->fProdFilter // Skip: m_info->fIPPlusConnector // Skip: m_info->fOCRRouter // Skip: m_info->fOCRConv // Skip: m_info->fPDFModule // Skip: m_info->fSerialValid ::fprintf(out, "SerialNumber: '%.*s'\n", sizeof(m_info->szSerialNumber), m_info->szSerialNumber); // Skip: m_info->fOEMCPMode ::fprintf(out, "LicensedChans: %d%s\n", m_info->sLiscensedChans, (m_info->sLiscensedChans == 0 ? ", unlimited" : "")); #if is_not_supported_yet__ // Skip: m_info->fSecureDoc // Skip: m_info->ulBumpBits // Skip: m_info->ulBumpDate t = m_info->ulBumpDate; ::sprintf(tbuf, "%02lX/%02lX/%04lX", t%0x10000/0x100, t%0x100, t/0x10000); ::fprintf(out, "BumpDate: %08lX, %s\n", m_info->ulBumpDate, tbuf); // Skip: m_info->fSMTPDisabled #endif // Skip: m_info->reserved ::fflush(out); } //------------------------------------------------------------------------------ // Public (non-class) functions //------------------------------------------------------------------------------ /******************************************************************************* * ::main() * Test the connection to a RightFax server. * * Usage * rfaxping host * *------------------------------------------------------------------------------- * @param argc * Argument count, i.e., the number of elements in 'argv[]'. * * @param argv * Command line arguments. * * @since 1.1, 2008-04-03 */ int main(int argc, char *argv[]) { // Execute this program return RFaxPinger::main(argc, (const char *const *)argv); } // End rfaxping.cpp