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: }