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: PetscCall(PetscMalloc1(mlen + nlen + 100, &body));
61: PetscCall(PetscStrcpy(body, "User="));
62: PetscCall(PetscStrcat(body, Username));
63: PetscCall(PetscStrcat(body, "&Password="));
64: PetscCall(PetscStrcat(body, Password));
65: PetscCall(PetscStrcat(body, "&PhoneNumbers[]="));
66: PetscCall(PetscStrcat(body, number));
67: PetscCall(PetscStrcat(body, "&"));
68: PetscCall(PetscStrcat(body, "Message="));
69: PetscCall(PetscStrcat(body, message));
70: PetscCall(PetscStrlen(body, &blen));
71: for (i = 0; i < (int)blen; i++) {
72: if (body[i] == ' ') body[i] = '+';
73: }
74: PetscCall(PetscSSLInitializeContext(&ctx));
75: PetscCall(PetscHTTPSConnect("app.tellmycell.com", 443, ctx, &sock, &ssl));
76: PetscCall(PetscHTTPSRequest("POST", "app.tellmycell.com/sending/messages?format=json", NULL, "application/x-www-form-urlencoded", body, ssl, buff, sizeof(buff)));
77: PetscCall(PetscSSLDestroyContext(ctx));
78: close(sock);
79: PetscCall(PetscFree(body));
80: if (flg) {
81: char *found;
82: PetscCall(PetscStrstr(buff, "\"success\":tr", &found));
83: *flg = found ? PETSC_TRUE : PETSC_FALSE;
84: }
85: }
86: PetscFunctionReturn(PETSC_SUCCESS);
87: }