Actual source code: tellmycell.c


  2: #include <petscwebclient.h>

  4: /*@C
  5:      PetscTellMyCell - Sends an SMS to an American/Canadian phone number

  7:    Not Collective, only the first process in `MPI_Comm` does anything

  9:    Input Parameters:
 10: +  comm - the MPI communicator
 11: .  number - the 10 digit telephone number
 12: -  message - the message

 14:    Output Parameter:
 15: .   flg - `PETSC_TRUE` if the text was sent

 17:    Options Database Keys:
 18: +   -tellmycell <number[,message]> - send a message to the give number when the program ends
 19: .   -tellmycell_user <Username> - this value is created when registering at tellmycell.com
 20: -   -tellmycell_password <Password> - this value is created when registering at tellmycell.com

 22:    Level: intermediate

 24:    Notes:
 25:     You must register for an account at tellmycell.com (you get 10 free texts with registration)

 27:    You must provide `-tellmycell_user <Username>` and `-tellmycell_password <Password>` in the options database

 29:    It would be nice to provide this as a free service but that would require making the PETSc TellMyCell password public.

 31:    Developer Note:
 32:     Perhaps the Username and Password should be arguments to this function.

 34: .seealso: `PetscTextBelt()`, `PetscHTTPSRequest()`, `PetscHTTPSConnect()`, `PetscSSLInitializeContext()`
 35: @*/
 36: PetscErrorCode PetscTellMyCell(MPI_Comm comm, const char number[], const char message[], PetscBool *flg)
 37: {
 38:   size_t      nlen, mlen, blen;
 39:   PetscMPIInt rank;
 40:   char        Username[64], Password[64];

 42:   PetscFunctionBegin;
 43:   PetscCall(PetscStrlen(number, &nlen));
 44:   PetscCheck(nlen == 10, comm, PETSC_ERR_ARG_WRONG, "Number %s is not ten digits", number);
 45:   PetscCall(PetscStrlen(message, &mlen));
 46:   PetscCheck(mlen <= 100, comm, PETSC_ERR_ARG_WRONG, "Message  %s is too long", message);
 47:   PetscCallMPI(MPI_Comm_rank(comm, &rank));
 48:   if (rank == 0) {
 49:     int       sock;
 50:     char      buff[1000], *body;
 51:     PetscInt  i;
 52:     SSL_CTX  *ctx;
 53:     SSL      *ssl;
 54:     PetscBool set;

 56:     PetscCall(PetscOptionsGetString(NULL, NULL, "-tellmycell_user", Username, sizeof(Username), &set));
 57:     PetscCheck(set, PETSC_COMM_SELF, PETSC_ERR_USER, "You must pass in a tellmycell user name with -tellmycell_user <Username>");
 58:     PetscCall(PetscOptionsGetString(NULL, NULL, "-tellmycell_password", Password, sizeof(Password), &set));
 59:     PetscCheck(set, PETSC_COMM_SELF, PETSC_ERR_USER, "You must pass in a tellmycell password with -tellmycell_password <Password>");
 60:     blen = mlen + nlen + 100;
 61:     PetscCall(PetscMalloc1(blen, &body));
 62:     PetscCall(PetscStrncpy(body, "User=", blen));
 63:     PetscCall(PetscStrlcat(body, Username, blen));
 64:     PetscCall(PetscStrlcat(body, "&Password=", blen));
 65:     PetscCall(PetscStrlcat(body, Password, blen));
 66:     PetscCall(PetscStrlcat(body, "&PhoneNumbers[]=", blen));
 67:     PetscCall(PetscStrlcat(body, number, blen));
 68:     PetscCall(PetscStrlcat(body, "&", blen));
 69:     PetscCall(PetscStrlcat(body, "Message=", blen));
 70:     PetscCall(PetscStrlcat(body, message, blen));
 71:     PetscCall(PetscStrlen(body, &blen));
 72:     for (i = 0; i < (int)blen; i++) {
 73:       if (body[i] == ' ') body[i] = '+';
 74:     }
 75:     PetscCall(PetscSSLInitializeContext(&ctx));
 76:     PetscCall(PetscHTTPSConnect("app.tellmycell.com", 443, ctx, &sock, &ssl));
 77:     PetscCall(PetscHTTPSRequest("POST", "app.tellmycell.com/sending/messages?format=json", NULL, "application/x-www-form-urlencoded", body, ssl, buff, sizeof(buff)));
 78:     PetscCall(PetscSSLDestroyContext(ctx));
 79:     close(sock);
 80:     PetscCall(PetscFree(body));
 81:     if (flg) {
 82:       char *found;
 83:       PetscCall(PetscStrstr(buff, "\"success\":tr", &found));
 84:       *flg = found ? PETSC_TRUE : PETSC_FALSE;
 85:     }
 86:   }
 87:   PetscFunctionReturn(PETSC_SUCCESS);
 88: }