"Fossies" - the Fresh Open Source Software Archive

Member "smslink-0.56b-3/contrib/send_sms/send_sms.cpp" (15 Nov 2005, 18346 Bytes) of package /linux/misc/old/smslink-0.56b-3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "send_sms.cpp" see the Fossies "Dox" file reference documentation.

    1 /*==========================================================
    2  * Program : send_sms.cpp             
    3  * Author  : Melle Sprenger (mellie@xs4all.nl)
    4  * 
    5  * Date    : 23/06/2000
    6  * Version : 0.1
    7  * License : GNU GENERAL PUBLIC LICENSE
    8  *           Version 2, June 1991
    9  *
   10  * Comment : Win32 commandline client for SMS Link server
   11  *=========================================================*/
   12 
   13 #include <condefs.h>
   14 #include <iostream.h>
   15 #include <winsock.h>
   16 #include <stdio.h>
   17 #include <winsock.h>
   18 #include <conio.h>
   19 #include <io.h>
   20 #include <fcntl.h>
   21 
   22 // Prototypes of the functions used
   23 SOCKET OpenSocket(char *sServer,short iPortNumber);
   24 int SendSMS(SOCKET socketSMS, char *sMessage, char *sUser, char *sDest, char *sSMSC);
   25 int WaitForPrompt(SOCKET socketSMS, bool bCheckOk = true);
   26 int SendToSocket(SOCKET socketSMS,char *sCommand);
   27 
   28 // Defines of the error values used in this SMS client
   29 #define SUCCESS           0
   30 #define ERR_SOCK_TIMEOUT  1
   31 #define ERR_SOCK_RECIEVE  2
   32 #define ERR_SOCK_SEND     3
   33 #define ERR_SOCK_INIT     4
   34 #define ERR_SOCK_CONNECT  5
   35 #define ERR_SOCK_SETOPT   6
   36 #define ERR_SOCK_NOACCESS 7
   37 #define ERR_SOCK_DISCONN  8
   38 #define ERR_CFG_OPEN      9
   39 #define ERR_PHONE_OPEN    10
   40 #define ERR_WRONG_PARAMS  11
   41 #define ERR_WINSOCK_DLL   12
   42 #define ERR_HOSTNOTFOUND  13
   43 #define ERR_SMS_ERROR     14
   44 
   45 // SMS client specific defines
   46 #define SOCKET_TIMEOUT 15         // Timeout value in seconds for socket
   47 //#define DEBUG                   // uncomment this line out for more
   48                                   // screenoutput and user-input
   49 
   50 // SMS server specific defines
   51 #define SMS_PROMPT  "SMS> "            // SMS server prompt
   52 #define SMS_SUCCESS "Ok"               // SMS server's string that indicates successful command execution
   53 #define SMS_SENT    "message sent OK"  // SMS server's respond after an SMS has been sent
   54 
   55 //------------------------- Main ---------------------------------------------//
   56 void main(int argc, char **argv)
   57 {
   58   int iReturn;                // return value
   59   FILE *hCfgFile;             // handle to config file
   60   FILE *hPhoneFile;           // handle to file containing multiple phonenumbers
   61   short iPortNumber;          // SMS server's port number
   62   char sCfgFile[256],         // The filename of the config file
   63        sServer[256],          // SMS server's IP address
   64        sSMSC[64],             // SMS Service Centre's phone number
   65        sMessage[170],         // Message we'll send
   66        sPhone[256],           // Second parameter, can be a phonenumber or a filename
   67        sDest[64],             // Destination phone number
   68        sUser[64],             // Username for SMS server
   69        sBuffer[256];          // Buffer used to read config file
   70   SOCKET  socketSMS;          // Handle to the socket used
   71   bool bPhoneNumber = true;   // Do we have a phonenumber, or a file with multiple numbers?
   72 
   73 
   74   printf("\n  Send_sms version 0.1, Copyright (C) 2000 Melle Sprenger");
   75   printf("\n  Send_sms comes with ABSOLUTELY NO WARRANTY.");
   76   printf("\n  This is free software, and you are welcome to redistribute it");
   77   printf("\n  under certain conditions; read license.txt for details.");
   78 
   79   // Construct the name of the config file
   80   strcpy(sCfgFile,argv[0]);
   81   sCfgFile[strlen(sCfgFile) - 3] = '\0';
   82   strcat(sCfgFile,"CFG");
   83 
   84   // Check commandline parameters
   85   if (argc != 3)
   86   {
   87     printf("\n\nUsage: send_sms \"msg\" \<phone\>\|\<list\>");
   88     printf("\n\n----------------------------------------------");
   89     printf("\n\n msg  : SMS message to send, between quotes");
   90     printf("\n\n phone: phone number to send SMS to.");
   91     printf("\n        (int. format, e.g. +31655108229)");
   92     printf("\n\n list : full path to file containing a list");
   93     printf("\n        of phone numbers to send SMS to");
   94     printf("\n\n----------------------------------------------");
   95     printf("\n\n\n press any key to exit...");
   96     getch();
   97     exit(ERR_WRONG_PARAMS);
   98   }
   99 
  100   // Set message to first commandline argument
  101   strcpy(sMessage,"\0");
  102   strcat(sMessage,argv[1]);
  103 
  104   // Set destination to second commandline argument
  105   strcpy(sPhone,"\0");
  106   strcpy(sPhone,argv[2]);
  107 
  108   // Here we could maybe place the local hostname as the user that is
  109   // sent to the SMS server TODO...
  110   strcpy(sUser,"w32smsclient");
  111 
  112   // Open the config file for read
  113   hCfgFile = fopen(sCfgFile, "r");
  114   if (hCfgFile == NULL)
  115      exit(ERR_CFG_OPEN);
  116 
  117   // The config file should consist of 3 lines, containing the following information:
  118   //
  119   // ipaddress sms server
  120   // sms_serv port
  121   // sms service centre
  122   //
  123   // This way of reading a config file is not really the best way to do it i guess.
  124   // we should probably use a proper .ini file and some more robust code for this.
  125   // for now this quick hack works though... TODO...
  126   int iStrPos,iChar;
  127 
  128   for (int iLine = 0; iLine < 3; iLine++)
  129   {
  130     iStrPos = 0;
  131 
  132     // Read a line, char by char and put it into sBuffer
  133     while ((iChar = (char)fgetc(hCfgFile)) != '\n')
  134     {
  135        sBuffer[iStrPos] = (char) iChar;
  136        iStrPos++;
  137     }
  138     // Close the sBuffer
  139     sBuffer[iStrPos] = '\0';
  140 
  141     // Put the data in sBuffer into the appropriate string
  142     switch(iLine)
  143     {
  144       case 0: // first line is the SMS server's IP address
  145         strcpy(sServer,sBuffer);
  146         break;
  147       case 1:  // second line is the SMS server's port number
  148         iPortNumber = atoi(sBuffer);
  149         break;
  150       case 2: // third line is the SMS Service Centre
  151         strcpy(sSMSC,sBuffer);
  152         break;
  153       default:
  154         break;
  155     }
  156   }
  157   // close the config file
  158   fclose(hCfgFile);
  159 
  160   // Check the sPhone string. If it is not a phonenumber (starting with "+")
  161   // we're gonna check if we can open the file
  162   if (sPhone[0] != '+')
  163   {
  164     bPhoneNumber = false;
  165     hPhoneFile = fopen(sPhone, "r");
  166     if (hPhoneFile == NULL)
  167     {
  168       printf("\nCould not open phonefile : %s",sDest);
  169       getch();
  170       exit(ERR_PHONE_OPEN);
  171     }
  172   }
  173   else
  174     strcpy(sDest,sPhone);
  175 
  176   // open a socket to the SMS server
  177   // after this call we should check if the socket is really there :-) TODO...
  178   socketSMS = OpenSocket(sServer,iPortNumber);
  179   if (socketSMS == NULL)
  180     exit(ERR_SOCK_INIT);
  181   // If the second parameter was a phonenumber send the SMS
  182   if (bPhoneNumber)
  183     iReturn = SendSMS(socketSMS, sMessage, sUser, sDest, sSMSC);
  184 
  185   // If the second parameter was a file, read it and send the SMS message
  186   // for every phonenumber in the file
  187   else
  188   {
  189     printf("\n\nSending multiple SMS's using %s\n", sPhone);
  190 
  191     // quick and dirty way to set strlen(sDest) bigger than 4
  192     strcpy(sDest,"what is the question to which the answer is 42?");
  193 
  194     // if the last read string from the file is shorter than 4, we'll assume we
  195     // have to quit. We should ofcourse find a more elegant way to read and
  196     // analyze the file with phonenumbers. Since the length of a phonenumber is
  197     // always > 4 this works for now :-)
  198     while (strlen(sDest) > 4)
  199     {
  200       iStrPos = 0;
  201       // Read a line, char by char and put it into sBuffer while we're not at EOF
  202       while ((iChar = (char)fgetc(hPhoneFile)) != '\n' && !feof(hPhoneFile))
  203       {
  204          sBuffer[iStrPos] = (char) iChar;
  205          iStrPos++;
  206       }
  207       // Close the sBuffer
  208       sBuffer[iStrPos] = '\0';
  209       // Copy the the read string from the phonenumber file into sDest
  210       strcpy(sDest,sBuffer);
  211       // Send the SMS message to the number read (only if we're not at EOF)
  212       if (!feof(hPhoneFile))
  213         iReturn = SendSMS(socketSMS, sMessage, sUser, sDest, sSMSC);
  214       else
  215         iReturn = 0;
  216 
  217       // If an error occured sending the SMS, we'll close and reopen the socket
  218       // just to be sure it will work for the next SMS to send (hopefully :-)
  219       if (iReturn != 0)
  220       {
  221         SendToSocket(socketSMS,"exit\r\n");
  222         closesocket(socketSMS);
  223         socketSMS = OpenSocket(sServer,iPortNumber);
  224       }
  225     }
  226   // close the phone file
  227   fclose(hPhoneFile);
  228   }
  229   // close the connection by sending the "exit" command
  230   SendToSocket(socketSMS,"exit\r\n");
  231   // Just to be sure we'll close the connection from our side too :-)
  232   closesocket(socketSMS);
  233   // Release WinSock and exit with the return code
  234   WSACleanup();
  235   #ifdef DEBUG
  236   printf("Exiting, lasterror = %i",iReturn);
  237   getch();
  238   #endif
  239   exit(iReturn);
  240 }
  241 
  242 //------------------------- SendSMS ------------------------------------------//
  243 // function that sends the SMS message
  244 //
  245 // Arguments:
  246 //               -socketSMS      Pointer to a socket connected to the SMS server
  247 //               -sMessage       Message to send
  248 //               -sUser          Username to send to the SMS server
  249 //               -sDest          Destination phone number
  250 //               -sSMSC          Phone number of the SMS Service Centre
  251 //
  252 // Return value: integer (0 if succesfull)
  253 //
  254 //----------------------------------------------------------------------------//
  255 
  256 int SendSMS(SOCKET socketSMS,   // the open socket to the SMS Server
  257             char *sMessage,     // Message to send
  258             char *sUser,        // Username to send to SMS server
  259             char *sDest,        // Destination phone number
  260             char *sSMSC)        // SMS Service Centre
  261 {
  262   // Print some info to the screen...
  263   printf("\nSending SMS message to %s...",sDest);
  264   // Start SMS sending sequence
  265   char sCmd[256];
  266   int i = 0;
  267   int iReturn;
  268 
  269   iReturn = SUCCESS;
  270 
  271   // Go through command sequence while return value is SUCCESS
  272   while (iReturn == SUCCESS)
  273   {
  274     i++;
  275     switch(i)  // set the command to send to the SMS server
  276     {
  277       case 1: // set username
  278         sprintf(sCmd,"set user = \"%s\"\r\n",sUser);
  279         break;
  280       case 2: // set message
  281         sprintf(sCmd,"set msg = \"%s\"\r\n",sMessage);
  282         break;
  283       case 3: // set destination phone number
  284         sprintf(sCmd,"set dest = %s\r\n",sDest);
  285         break;
  286       case 4: // set SMS Service Centre number
  287         sprintf(sCmd,"set smsc = %s\r\n",sSMSC);
  288         break;
  289       case 5: // send the message
  290         sprintf(sCmd,"send\r\n");
  291         break;
  292       default: // if the "send" command returns, we'll quit
  293         printf("done!");
  294         return(iReturn);
  295         break;
  296     }
  297     // if we got a prompt, send the command to the SMS server
  298     iReturn = SendToSocket(socketSMS,sCmd);
  299     // Command should have been set, now check if we get a prompt from the SMS Server
  300     if (iReturn == SUCCESS)
  301       iReturn = WaitForPrompt(socketSMS);
  302     if (iReturn == SUCCESS)
  303       printf(".");
  304   }
  305   // if the returncode is not SUCCESS we'll stop and return the error to main()
  306   printf("error!");
  307   return(iReturn);
  308 }
  309 
  310 
  311 //------------------------- WaitForPrompt ------------------------------------//
  312 // This function reads the incoming data from the SMS server and waits for
  313 // the SMS server's prompt. If no incoming data is detected for SOCKET_TIMEOUT
  314 // seconds the function returns
  315 //
  316 // Arguments:
  317 //               -socketSMS      Pointer to a socket connected to the SMS server
  318 //               -bCheckOK       boolean to indicate wether the function should
  319 //                               check if the recieved buffer before the prompt
  320 //                               contains the string SMS_SUCCESS (default=true)
  321 //
  322 // Return value: integer (0 if succesfull)
  323 //
  324 //----------------------------------------------------------------------------//
  325 
  326 int WaitForPrompt(SOCKET socketSMS, bool bCheckOk)
  327 {
  328   char sBuf[256],         // string to hold the last recieved data
  329        sResponse[2048];   // string to hold the recieved data since the last prompt
  330 
  331   int iReturn;
  332   fd_set ReadAbleSock;            // Mask for select() function
  333   struct timeval  TimeOut;    // timeout structure
  334   struct timeval *pTimeOut;   // timeout structure
  335 
  336   // Set the socket timeout value
  337   TimeOut.tv_sec = SOCKET_TIMEOUT;
  338   TimeOut.tv_usec=0;
  339   pTimeOut = &TimeOut;
  340   // reset the sResponse string AND the sBuf string (NEVER forget to initialize
  341   // chars i guess... took me about an hour to figure this out
  342   strcpy(sResponse,"\0");
  343   strcpy(sBuf,"\0");
  344 
  345   // Get the data sent by the SMS server until we have a prompt
  346   while ( strstr(sBuf,SMS_PROMPT) == NULL)
  347   {
  348     // reset mask and set the socket we are using. If not our application could
  349     // cause other programs serious trouble :-) (although Win32 docs tell us something
  350     // completely different)
  351     FD_ZERO (&ReadAbleSock);
  352     FD_SET (socketSMS, &ReadAbleSock);
  353 
  354     // Poll the socket for pending data and check if it doesn't timeout
  355     iReturn = select(socketSMS+1, &ReadAbleSock, NULL, NULL, pTimeOut);
  356 
  357     // If select() returns an error we'll quit...
  358     if (iReturn == SOCKET_ERROR)
  359       return(ERR_SOCK_RECIEVE);
  360 
  361     // else if the socket is alive, hasn't timed out and there's data waiting,
  362     // get the data
  363     else if (FD_ISSET(socketSMS,&ReadAbleSock))
  364     {
  365       strcpy(sBuf,"\0");
  366       iReturn = recv(socketSMS,               // Connected socket
  367                      sBuf,                    // Receive buffer
  368                      sizeof(sBuf),            // Size of receive buffer
  369                      0);                      // Flags
  370       // If we couldn't recieve data from the socket we'll 'die'
  371       if (iReturn == SOCKET_ERROR)
  372         return(ERR_SOCK_RECIEVE);
  373       // If recv() returns "0" (no chars recieves) the server gracefully
  374       // ended out connection
  375       if (iReturn == 0)
  376         return(ERR_SOCK_DISCONN);
  377       // We close the buffer since we'll get garbage at the end otherwise
  378       sBuf[iReturn] = '\0';
  379       // print the buffer to screen an append it to the sResponse buffer
  380       #ifdef DEBUG
  381       printf("%s", sBuf);
  382       #endif
  383       strcat(sResponse,sBuf);
  384     }
  385     // if no data is waiting and select returns "0" the socket has timed out :-(
  386     else
  387       return(ERR_SOCK_TIMEOUT);
  388   }
  389   // check if the SMS server understood what we were telling him/her
  390   // In case the message is sent ok we might want to extract the message id from the
  391   // sResponse string too. It might also be a good idea to let this function somehow
  392   // return the sResponse string so we can evaluate that inside the SendSMS()
  393   // function and take actions there TODO..
  394   if (strstr(sResponse,SMS_SUCCESS) || strstr(sResponse, SMS_SENT) || !bCheckOk )
  395     return(SUCCESS);
  396 
  397    // if he/she did not, return an SMS_ERROR. We should probably look at the sResponse
  398   // string and see what went wrong here, so we can deal with it a little bit more
  399   // intelligent as opposed to just quitting with an SMS_ERROR  TODO...
  400   else
  401     return(ERR_SMS_ERROR);
  402 }
  403 
  404 //------------------------- SendToSocket -------------------------------------//
  405 // Sends a string to the connected socket
  406 //
  407 // Arguments:
  408 //               -socketSMS      Pointer to a socket connected to the SMS server
  409 //               -sCommand       Command to send to the SMS server
  410 //
  411 // Return value: integer (0 if succesfull)
  412 //
  413 //----------------------------------------------------------------------------//
  414 
  415 int SendToSocket(SOCKET socketSMS, char *sCommand)
  416 {
  417   int iReturn;
  418   // print the command to screen so we can see wat's going on (local echo)
  419   #ifdef DEBUG
  420   printf("%s",sCommand);
  421   #endif
  422   // send the command to the socket
  423   iReturn = send(socketSMS,           // Connected socket
  424                  sCommand,            // Data buffer to send
  425                  strlen(sCommand),    // Length of data buffer
  426                  0);                  // Flags
  427   // if we got a socket error we'll just 'die'
  428   if (iReturn == SOCKET_ERROR)
  429     return(ERR_SOCK_SEND);
  430   //string sent successfully
  431   return(SUCCESS);
  432 }
  433 
  434 //------------------------- OpenSocket -------------------------------------//
  435 // Initialises and opens the socket connection
  436 //
  437 // Arguments:
  438 //               -sSMS           SMS server IP address
  439 //               -iPortNumber    Portnumber to which the SMS server is listening
  440 //
  441 // Return value: Pointer to the connected socket
  442 //
  443 //----------------------------------------------------------------------------//
  444 SOCKET OpenSocket(char *sServer, short iPortNumber)
  445 {
  446   int iReturn;
  447   SOCKET socketSMS;
  448   WORD wVersionRequested;     // Windsock version we want
  449   WSADATA wsaData;            // Windows socket data buffer
  450 
  451   // Initialize WinSock and check for the correct version
  452   wVersionRequested = MAKEWORD(1,1);
  453   iReturn = WSAStartup(wVersionRequested, &wsaData);
  454 
  455   // If the version is not what we expected we'll just 'die' for now
  456   if (wsaData.wVersion != wVersionRequested)
  457       return(NULL);
  458 
  459   // Find the SMS server
  460   LPHOSTENT lpHostEntry;
  461   lpHostEntry = gethostbyname(sServer);
  462   if (lpHostEntry == NULL)
  463     return(NULL);
  464 
  465   // Create a socket connection to the SMS Server
  466   socketSMS = socket(AF_INET,             // Address family
  467                      SOCK_STREAM,         // Socket type
  468                      IPPROTO_TCP);        // Protocol
  469   if (socketSMS == INVALID_SOCKET)
  470     return(socketSMS);
  471 
  472   // Fill in the socket address structure
  473   SOCKADDR_IN saServer;
  474   saServer.sin_family = AF_INET;
  475   saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
  476   saServer.sin_port = htons(iPortNumber);
  477 
  478   printf("\n\nConnecting to server %s on port %d...", sServer, iPortNumber);
  479   // connect to the server
  480   iReturn = connect(socketSMS,                // Socket
  481                     (LPSOCKADDR)&saServer,    // Server address
  482                     sizeof(struct sockaddr)); // Length of server address structure
  483 
  484   // if we don't get a connection we'll just 'die' with the appropriate error
  485   // we probably should have some retry mechanism here, so a temporarily network
  486   // problem won't spoil the fun... TODO...
  487   if (iReturn == SOCKET_ERROR)
  488     return(NULL);
  489   printf("connected!\n");
  490   iReturn = WaitForPrompt(socketSMS, false);
  491   if (iReturn == 0)
  492     return(socketSMS);
  493   else
  494     return(NULL);
  495 }
  496