push.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * Sapphire backend
  3. *
  4. * Copyright (C) 2018 Alyssa Rosenzweig
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
  19. *
  20. */
  21. #include "push.h"
  22. #include "websocket.h"
  23. /* Has a push notification been sent since the last login? We default to TRUE
  24. * to avoid sporadic push notifications before the first connection*/
  25. gboolean sapphire_already_pushed = TRUE;
  26. /* We got a connection, so we're clear for another push */
  27. void
  28. sapphire_push_connected(void)
  29. {
  30. sapphire_already_pushed = FALSE;
  31. }
  32. /* Send a push notification with the given content. This wrapper function
  33. * determines whether the notification should actually be pushed, handling
  34. * state appropriately. Actual medium-specific sending is delegated. */
  35. static void sapphire_push_notification_raw(const gchar *content);
  36. void
  37. sapphire_push_notification(const gchar *content)
  38. {
  39. /* Push notifications can only be sent if:
  40. *
  41. * 0. Push notifications are enabled (TODO)
  42. * 1. There are no connected clients
  43. * 2. There has not been another push notification sent
  44. *
  45. * Check these criteria
  46. */
  47. if (sapphire_any_connected_clients()) return;
  48. if (sapphire_already_pushed) return;
  49. /* We've passed the criteria, so send the notification */
  50. sapphire_push_notification_raw(content);
  51. /* Record that we pushed something */
  52. sapphire_already_pushed = TRUE;
  53. }
  54. /* Actually send the push notification (medium-specific). At the moment, push
  55. * notifications are email-based, allowing for SMS beeps via SMS-email bridge,
  56. * etc */
  57. static
  58. void sapphire_push_notification_raw(const gchar *content)
  59. {
  60. /* Send push notification as the body of an email via mailx. First,
  61. * write the content to a file */
  62. const char *temp_file = "/dev/shm/push-notification.txt";
  63. FILE *fp = fopen(temp_file, "w");
  64. fputs(content, fp);
  65. fclose(fp);
  66. /* Find the target mail address */
  67. const char *address = purple_prefs_get_string(SAPPHIRE_PUSH_EMAIL_PREF);
  68. /* Strip whitespace so it's zero length if blank */
  69. gchar *stripped = g_strstrip(g_strdup(address));
  70. if (stripped[0] == '\0') {
  71. printf("Can't do push notifications to empty address, thonk\n");
  72. return;
  73. }
  74. /* Now, invoke mailx via system. XXX: SECURITY: Sanitize the address */
  75. gchar *command = g_strdup_printf("mailx -- %s < %s", stripped, temp_file);
  76. printf("Invoking %s\n", command);
  77. system(command);
  78. g_free(command);
  79. g_free(stripped);
  80. printf("Pushing %s\n", content);
  81. }