PageRenderTime 28ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/code_comm/mailnotify.c

http://research-code-base-animesh.googlecode.com/
C | 770 lines | 610 code | 105 blank | 55 comment | 77 complexity | cc9da35f1dd68bb1238e1d8d724a5fe6 MD5 | raw file
  1. /*
  2. * mailnotify.c
  3. *
  4. * xmms plugin that checks for new mail and will soon be able
  5. * to play selected music relating to the sender of the new mail on arrival.
  6. *
  7. * get the latest version from http://iso.kapsobor.de/xmms/
  8. *
  9. * iso:crash <mailnotify@kapsobor.de>
  10. *
  11. * ----------------------------- */
  12. #define MAX_ERRORS 5
  13. #define MAX_ORIGINS 128
  14. #define DEFAULT_INTERVAL 10
  15. #define MAX_FOLDERS 64
  16. #define DEFAULT_ALERT_FILE "/usr/lib/xmms/General/alert.wav"
  17. #define DEFAULT_POPUP_COMMAND "xterm -e mutt -f %MB"
  18. #define CONTINUE_WHERE_INTERRUPTED 1
  19. #define SIZE_TOLERANCE 100
  20. /* #define DEBUG */
  21. /* ---------------------------- */
  22. #define VERSION "0.2.0"
  23. #include <pthread.h>
  24. #include <gtk/gtk.h>
  25. #include "xmmsctrl.h"
  26. #include "util.h"
  27. #include <plugin.h>
  28. #include "configfile.h"
  29. #include <unistd.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <fcntl.h>
  34. #include <errno.h>
  35. #include <sys/stat.h>
  36. #include <dirent.h>
  37. #include <regex.h>
  38. #ifdef PWDINSYS
  39. # include <sys/pwd.h>
  40. #else
  41. # include <pwd.h>
  42. #endif
  43. #ifndef ANSI_C
  44. extern struct passwd *getpwnam(), *getpwuid();
  45. extern char *genenv();
  46. #endif
  47. #ifdef I_TIME
  48. # include <time.h>
  49. #endif
  50. #ifdef I_SYSTIME
  51. # include <sys/time.h>
  52. #endif
  53. #ifdef BSD
  54. # include <sys/timeb.h>
  55. #endif
  56. #ifdef I_UTIME
  57. # include <utime.h>
  58. #endif
  59. #ifdef I_SYSUTIME
  60. # include <sys/utime.h>
  61. #else
  62. # include <utime.h>
  63. #endif
  64. gint all_folders = 0;
  65. long bytes();
  66. gint isdir();
  67. struct folder {
  68. char foldername[256];
  69. char prefix[48];
  70. long filesize;
  71. int xs_errors;
  72. gchar sender[256];
  73. gchar command[256];
  74. gboolean runcmd;
  75. gchar alertfile[256];
  76. } folders[MAX_FOLDERS] = {0};
  77. struct origin {
  78. gchar senderaddr[256];
  79. gboolean runcmd;
  80. gchar command[256];
  81. gchar alertfile[256];
  82. } origins[MAX_ORIGINS] = {0};
  83. /* #if !defined(UTIMBUF)
  84. struct utimbuf {
  85. time_t actime;
  86. time_t modtime;
  87. };
  88. #endif */
  89. FILE *fd = NULL;
  90. #if defined (BSD) && !defined(UTIMBUF)
  91. time_t utime_buffer[2];
  92. #else
  93. struct utimbuf utime_buffer;
  94. #endif
  95. extern int errno;
  96. static GtkWidget *conf_dialog, *about_win;
  97. static pthread_t tid;
  98. static GtkWidget *mailboxname_entry, *alertfile_entry, *command_entry, *seconds_entry, *popup_check;
  99. void *mailnotify_thread(void *args);
  100. void mailnotify_init(void);
  101. void mailnotify_about(void);
  102. void mailnotify_config(void);
  103. void mailnotify_config_save(GtkWidget *wid, gpointer data);
  104. void mailnotify_cleanup(void);
  105. void get_default_folder(void);
  106. void new_mail_notification();
  107. int read_sender();
  108. void register_folders(void);
  109. void check_config(void);
  110. /* the configurable options */
  111. static gchar *mailboxname = NULL;
  112. static gchar *alertfile = NULL;
  113. static gchar *popup_command = NULL;
  114. static gboolean popup_active;
  115. static gint check_seconds;
  116. static gboolean xfade_active;
  117. static gboolean origin_override = TRUE;
  118. static gint saved_position, saved_offset;
  119. gchar *about_text = "MailNofity "VERSION" checks for new mail and plays a selected file on arrival.\nIt will also run a configurable command if desired, e.g. launch your favorite mail client, i.e. mutt.\n\nmailnotify@kapsobor.de\nhttp://iso.kapsobor.de/xmms/";
  120. /* ------------ */
  121. GeneralPlugin mailnotify =
  122. {
  123. NULL,
  124. NULL,
  125. -1,
  126. "Mail Notify "VERSION,
  127. mailnotify_init,
  128. mailnotify_about,
  129. mailnotify_config,
  130. mailnotify_cleanup,
  131. };
  132. void mailnotify_cleanup(void)
  133. {
  134. pthread_cancel (tid);
  135. }
  136. GeneralPlugin *get_gplugin_info(void)
  137. {
  138. return (&mailnotify);
  139. }
  140. void read_config (GtkWidget *wid, gpointer data)
  141. {
  142. gchar *oppi;
  143. ConfigFile *config;
  144. #ifdef DEBUG
  145. printf("reading configuration");
  146. #endif
  147. if ((config = xmms_cfg_open_default_file()) != NULL)
  148. {
  149. xmms_cfg_read_string (config, "mailnotify", "mailboxname", &mailboxname);
  150. xmms_cfg_read_string (config, "mailnotify", "alertfile", &alertfile);
  151. xmms_cfg_read_boolean (config, "mailnotify", "popup_active", &popup_active);
  152. xmms_cfg_read_string (config, "mailnotify", "popup_command", &popup_command);
  153. xmms_cfg_read_int (config, "mailnotify", "check_seconds", &check_seconds);
  154. #ifdef DEBUG
  155. printf("looking for xfader plugin\n");
  156. #endif
  157. /* with xfader plugin activated we have to do some workaround */
  158. xmms_cfg_read_string (config, "xmms", "output_plugin", &oppi);
  159. }
  160. if(strstr(oppi, "libcrossfade.so") != NULL)
  161. xfade_active = TRUE;
  162. else
  163. xfade_active = FALSE;
  164. xmms_cfg_free(config);
  165. check_config();
  166. }
  167. void mailnotify_init(void)
  168. {
  169. pthread_attr_t attr;
  170. #ifdef DEBUG
  171. printf("initialisation phase\n");
  172. #endif
  173. read_config(NULL, NULL);
  174. pthread_attr_init(&attr);
  175. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  176. pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
  177. pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
  178. pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
  179. pthread_create(&tid, &attr, mailnotify_thread, NULL);
  180. return;
  181. }
  182. void *mailnotify_thread(void *args)
  183. {
  184. gint i, finalsize;
  185. long lastsize, newsize;
  186. register struct folder *current_folder;
  187. register_folders();
  188. /* warning: more folders option still missing here!! */
  189. while(1)
  190. {
  191. /** mail check loop *****/
  192. #ifdef DEBUG
  193. printf("Checking %d Folders, starting ..\n", all_folders);
  194. #endif
  195. for(i = 0; i < all_folders; i++)
  196. {
  197. current_folder = &folders[i];
  198. #ifdef DEBUG
  199. printf("Checking Folder #%d ( %s )\n", i + 1, current_folder->foldername);
  200. #endif
  201. if((newsize = bytes(current_folder->foldername)) == current_folder->filesize)
  202. {
  203. #ifdef DEBUG
  204. printf("Everything is okay. No new Mail has arrived. Size remains %ld bytes.\n", current_folder->filesize);
  205. #endif
  206. continue;
  207. }
  208. if ((fd = fopen(current_folder->foldername,"r")) == NULL)
  209. {
  210. if(errno == EACCES)
  211. {
  212. current_folder->xs_errors++;
  213. if(current_folder->xs_errors > MAX_ERRORS)
  214. {
  215. printf("Fatal: %d errors checking %s: Cannot access file.",MAX_ERRORS,current_folder->foldername);
  216. }
  217. }
  218. continue;
  219. }
  220. if ((newsize = bytes(current_folder->foldername)) > current_folder->filesize)
  221. {
  222. /* new mail has arrived, SIZE_TOLERANCE is required as little changes (f.e. flag toggles) could probably change the filesize */
  223. if( newsize > current_folder->filesize + SIZE_TOLERANCE)
  224. {
  225. #ifdef DEBUG
  226. printf("PANIC! New mail has arrived.\n");
  227. #endif
  228. if (fseek(fd, current_folder->filesize, 0) != 0)
  229. {
  230. printf("Fatal: Could not fseek to %ld in %s", current_folder->filesize, current_folder->foldername);
  231. }
  232. else
  233. {
  234. /* check for sender of new mail */
  235. read_sender(fd, current_folder);
  236. /* notify user by selected methods */
  237. new_mail_notification(current_folder);
  238. }
  239. }
  240. current_folder->filesize=newsize;
  241. #ifdef DEBUG
  242. printf("set new filesize %ld", current_folder->filesize);
  243. #endif
  244. #if defined(BSD) && !defined(UTIMBUG)
  245. utime(current_folder->foldername, utime_buffer);
  246. #else
  247. utime(current_folder->foldername, &utime_buffer);
  248. #endif
  249. }
  250. else
  251. {
  252. current_folder->filesize = bytes(current_folder->foldername);
  253. lastsize = current_folder->filesize;
  254. finalsize = 0;
  255. while(! finalsize)
  256. {
  257. sleep(1);
  258. newsize = bytes(current_folder->foldername);
  259. if (newsize != lastsize)
  260. lastsize = newsize;
  261. else
  262. finalsize++;
  263. }
  264. current_folder->filesize=newsize;
  265. }
  266. fclose(fd);
  267. }
  268. sleep(DEFAULT_INTERVAL);
  269. /* end of loop *****/
  270. }
  271. }
  272. /* the about window */
  273. void mailnotify_about(void)
  274. {
  275. GtkWidget *button, *label, *bigbox, *buttonbox, *textframe;
  276. if(about_win)
  277. return;
  278. about_win = gtk_window_new(GTK_WINDOW_DIALOG);
  279. gtk_window_set_title(GTK_WINDOW(about_win), ("About"));
  280. gtk_container_set_border_width(GTK_CONTAINER(about_win), 15);
  281. gtk_window_set_policy(GTK_WINDOW(about_win), FALSE, FALSE, FALSE);
  282. gtk_window_set_position(GTK_WINDOW(about_win), GTK_WIN_POS_MOUSE);
  283. textframe = gtk_frame_new ("XMMS Mail Notify Plugin:");
  284. bigbox = gtk_vbox_new(FALSE, 15);
  285. gtk_container_add(GTK_CONTAINER(about_win), bigbox);
  286. gtk_container_add(GTK_CONTAINER(bigbox), textframe);
  287. label = gtk_label_new(about_text);
  288. gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
  289. gtk_container_add(GTK_CONTAINER(textframe), label);
  290. buttonbox = gtk_hbutton_box_new();
  291. gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonbox), GTK_BUTTONBOX_DEFAULT_STYLE);
  292. gtk_button_box_set_spacing(GTK_BUTTON_BOX(buttonbox), 5);
  293. gtk_box_pack_start(GTK_BOX(bigbox), buttonbox, FALSE, FALSE, 0);
  294. gtk_signal_connect(GTK_OBJECT(about_win), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &about_win);
  295. button = gtk_button_new_with_label("Check.");
  296. GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
  297. gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) about_win);
  298. gtk_box_pack_start(GTK_BOX ((buttonbox)), button, FALSE, TRUE, 5);
  299. gtk_widget_show_all(about_win);
  300. }
  301. /* save config file */
  302. void mailnotify_config_save(GtkWidget *wid, gpointer data)
  303. {
  304. ConfigFile *config;
  305. #ifdef DEBUG
  306. printf("saving configuration\n");
  307. #endif
  308. if ((config = xmms_cfg_open_default_file()) == NULL)
  309. config = xmms_cfg_new();
  310. mailboxname = g_strdup(gtk_entry_get_text(GTK_ENTRY(mailboxname_entry)));
  311. alertfile = g_strdup(gtk_entry_get_text(GTK_ENTRY(alertfile_entry)));
  312. popup_command = g_strdup(gtk_entry_get_text(GTK_ENTRY(command_entry)));
  313. popup_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(popup_check));
  314. check_seconds = atoi(gtk_entry_get_text(GTK_ENTRY(seconds_entry)));
  315. xmms_cfg_write_string (config, "mailnotify", "mailboxname", mailboxname);
  316. xmms_cfg_write_string (config, "mailnotify", "alertfile", alertfile);
  317. xmms_cfg_write_string (config, "mailnotify", "popup_command", popup_command);
  318. xmms_cfg_write_boolean(config, "mailnotify", "popup_active", popup_active);
  319. xmms_cfg_write_int (config, "mailnotify", "check_seconds", check_seconds);
  320. xmms_cfg_write_default_file (config);
  321. xmms_cfg_free(config);
  322. return;
  323. }
  324. /* the config-ok button action */
  325. void mailnotify_config_ok(GtkWidget *wid, gpointer data)
  326. {
  327. mailnotify_config_save(NULL, NULL);
  328. gtk_widget_destroy(conf_dialog);
  329. conf_dialog = NULL;
  330. return;
  331. }
  332. /* the config window */
  333. void mailnotify_config(void)
  334. {
  335. GtkWidget *ok_button, *apply_button, *cancel_button, *buttonbox, *atable, *seconds_label_2,
  336. *bigbox, *checkframe, *actionframe, *mailboxname_label, *ctable, *alertfile_label, *seconds_label, *command_label;
  337. gchar *csbuf;
  338. if (conf_dialog)
  339. return;
  340. conf_dialog = gtk_window_new(GTK_WINDOW_DIALOG);
  341. #ifdef DEBUG
  342. printf("configuration window coming up\n");
  343. #endif
  344. /* configure window might popup before plugin is activated (and therefore before _init() is called */
  345. read_config(NULL, NULL);
  346. gtk_window_set_title(GTK_WINDOW(conf_dialog), ("XMMS MailNotify Configuration"));
  347. gtk_window_set_policy(GTK_WINDOW(conf_dialog), FALSE, FALSE, FALSE);
  348. gtk_window_set_position(GTK_WINDOW(conf_dialog), GTK_WIN_POS_MOUSE);
  349. gtk_container_set_border_width(GTK_CONTAINER(conf_dialog), 15);
  350. gtk_signal_connect(GTK_OBJECT(conf_dialog), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &conf_dialog);
  351. bigbox = gtk_vbox_new(FALSE, 5);
  352. gtk_container_add(GTK_CONTAINER (GTK_WINDOW(conf_dialog)), bigbox);
  353. checkframe = gtk_frame_new ("Check");
  354. gtk_container_add(GTK_CONTAINER(bigbox), checkframe);
  355. ctable = gtk_table_new(2, 4, FALSE);
  356. gtk_container_add(GTK_CONTAINER(checkframe), ctable);
  357. actionframe = gtk_frame_new ("Action");
  358. gtk_container_add(GTK_CONTAINER(bigbox), actionframe);
  359. atable = gtk_table_new(2, 3, FALSE);
  360. gtk_container_add(GTK_CONTAINER(actionframe), atable);
  361. mailboxname_label = gtk_label_new("Mailboxfile:");
  362. gtk_label_set_justify(GTK_LABEL(mailboxname_label), GTK_JUSTIFY_RIGHT);
  363. gtk_table_attach_defaults(GTK_TABLE(ctable), mailboxname_label, 0, 1, 0, 1 );
  364. alertfile_label = gtk_label_new("Alertfile:");
  365. gtk_table_attach_defaults(GTK_TABLE(atable), alertfile_label , 0, 1, 0, 1 );
  366. mailboxname_entry = gtk_entry_new();
  367. alertfile_entry = gtk_entry_new();
  368. if(mailboxname != NULL)
  369. gtk_entry_set_text(GTK_ENTRY(mailboxname_entry), mailboxname);
  370. if(alertfile != NULL)
  371. gtk_entry_set_text(GTK_ENTRY(alertfile_entry), alertfile);
  372. gtk_table_attach_defaults(GTK_TABLE(ctable), mailboxname_entry, 1, 4, 0, 1);
  373. gtk_table_attach_defaults(GTK_TABLE(atable), alertfile_entry, 1, 3, 0,1);
  374. seconds_label = gtk_label_new("Check every");
  375. gtk_table_attach_defaults(GTK_TABLE(ctable), seconds_label, 0, 1, 1, 2);
  376. seconds_label_2 = gtk_label_new("seconds.");
  377. gtk_label_set_justify(GTK_LABEL(seconds_label_2), GTK_JUSTIFY_LEFT);
  378. gtk_table_attach_defaults(GTK_TABLE(ctable), seconds_label_2, 2, 4, 1, 2);
  379. popup_check = gtk_check_button_new();
  380. if(popup_active)
  381. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(popup_check), TRUE);
  382. else
  383. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(popup_check), FALSE);
  384. gtk_table_attach_defaults(GTK_TABLE(atable), popup_check, 0,1,1,2);
  385. command_label = gtk_label_new("run command:");
  386. gtk_table_attach_defaults(GTK_TABLE(atable), command_label, 1, 2, 1, 2);
  387. seconds_entry = gtk_entry_new();
  388. command_entry = gtk_entry_new();
  389. gtk_widget_set_usize(seconds_entry, 10, -2);
  390. if(popup_command != NULL)
  391. gtk_entry_set_text(GTK_ENTRY(command_entry), popup_command);
  392. if(check_seconds)
  393. {
  394. csbuf = (char*) malloc(sizeof(gint) + 1);
  395. sprintf(csbuf, "%d", check_seconds);
  396. gtk_entry_set_text(GTK_ENTRY(seconds_entry), csbuf);
  397. }
  398. gtk_table_attach_defaults(GTK_TABLE(ctable), seconds_entry, 1, 2, 1, 2);
  399. gtk_table_attach_defaults(GTK_TABLE(atable), command_entry, 2, 3, 1, 2);
  400. buttonbox = gtk_hbutton_box_new();
  401. gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonbox), GTK_BUTTONBOX_END);
  402. gtk_button_box_set_spacing(GTK_BUTTON_BOX(buttonbox), 5);
  403. gtk_box_pack_start(GTK_BOX(bigbox), buttonbox, FALSE, FALSE, 0);
  404. ok_button = gtk_button_new_with_label("Ok");
  405. apply_button = gtk_button_new_with_label("Apply");
  406. cancel_button = gtk_button_new_with_label("Cancel");
  407. gtk_signal_connect_object(GTK_OBJECT(cancel_button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) conf_dialog);
  408. gtk_signal_connect_object(GTK_OBJECT(apply_button), "clicked", GTK_SIGNAL_FUNC (mailnotify_config_save), NULL);
  409. gtk_signal_connect_object(GTK_OBJECT(ok_button), "clicked", GTK_SIGNAL_FUNC (mailnotify_config_ok), NULL);
  410. GTK_WIDGET_SET_FLAGS(ok_button, GTK_CAN_DEFAULT);
  411. GTK_WIDGET_SET_FLAGS(cancel_button, GTK_CAN_DEFAULT);
  412. GTK_WIDGET_SET_FLAGS(apply_button, GTK_CAN_DEFAULT);
  413. gtk_box_pack_start(GTK_BOX(buttonbox), ok_button, TRUE, TRUE, 0);
  414. gtk_box_pack_start(GTK_BOX(buttonbox), apply_button, TRUE, TRUE, 0);
  415. gtk_box_pack_start(GTK_BOX(buttonbox), cancel_button, TRUE, TRUE, 0);
  416. gtk_widget_show_all(conf_dialog);
  417. }
  418. /* look for the default mailfolder */
  419. void get_default_folder(void)
  420. {
  421. gchar *incoming_folder, *user_name = "";
  422. gchar buf[256];
  423. struct passwd *pw;
  424. incoming_folder = (gchar *)getenv("MAIL");
  425. if (strlen(incoming_folder) < 1)
  426. {
  427. if((pw = getpwuid(geteuid())) == NULL)
  428. {
  429. #ifdef DEBUG
  430. printf("You are missing a passwd entry. Bailing out.\n");
  431. #endif
  432. }
  433. else
  434. {
  435. user_name = pw->pw_name;
  436. }
  437. if (isdir("/var/mail", NULL))
  438. {
  439. snprintf(buf, sizeof(buf), "/var/mail/%s", user_name);
  440. }
  441. else
  442. {
  443. snprintf(buf, sizeof(buf), "/var/spool/mail/%s", user_name);
  444. }
  445. mailboxname = g_strdup_printf("%s",buf);
  446. }
  447. else
  448. {
  449. mailboxname = incoming_folder;
  450. }
  451. }
  452. /* fsize */
  453. long bytes(name)
  454. char *name;
  455. {
  456. int check = 1;
  457. extern int errno;
  458. struct stat buffer;
  459. if (stat(name, &buffer) != 0)
  460. {
  461. if (errno != 2)
  462. {
  463. printf("Error %d while fstat on %s", errno, name);
  464. }
  465. else
  466. check = 0;
  467. }
  468. #if defined(BSD) && !defined(UTIMBUF)
  469. utime_buffer[0] = buffer.st_atime;
  470. utime_buffer[1] = buffer.st_mtime;
  471. #else
  472. utime_buffer.actime = buffer.st_atime;
  473. utime_buffer.modtime = buffer.st_mtime;
  474. #endif
  475. return (check ? buffer.st_size : 0);
  476. }
  477. /* check dir */
  478. int isdir(char *dir)
  479. {
  480. struct stat st;
  481. int result = FALSE;
  482. if (stat(dir, &st) == 0 && S_ISDIR(st.st_mode))
  483. result = TRUE;
  484. return result;
  485. }
  486. /* * * * * * * * *
  487. *
  488. * execute the popup_command if desired and play the file, i.e.
  489. * add the file to the playlist, play the last position and
  490. * try to figure out when it might be over, afterwards skip
  491. * back to the previously played file and continue playing.
  492. */
  493. void new_mail_notification(newmail_folder)
  494. register struct folder *newmail_folder;
  495. {
  496. gint curpos, afpos;
  497. static gboolean toggleshuffle = FALSE, wasplaying = TRUE;
  498. static gchar **list, *pcmd, *p, *argv[4] = {"/bin/sh", "-c", NULL, NULL};
  499. pid_t pid;
  500. #ifdef DEBUG
  501. gchar *dummy;
  502. printf("Incoming mail from %s\n", newmail_folder->sender);
  503. #endif
  504. /* beschraenkter mist: jetzt geht das aber erstmal nur, wenn %mb am ende steht. autsch! */
  505. /* list auch entsprechend nach newmail_folder->sender aussuchen!! */
  506. list = g_malloc0((strlen(alertfile) + 4) * sizeof(gchar *));
  507. pcmd = g_malloc0((strlen(mailboxname) + strlen(popup_command)) * sizeof(gchar *));
  508. /* play file responding to newmail_folder->sender (missing!) */
  509. list[0] = alertfile;
  510. /* popup if desired */
  511. if((popup_active) && (popup_command != NULL))
  512. {
  513. /* replace %MB in cmdstring w/ mailbox name */
  514. strcpy(pcmd, popup_command);
  515. if((p = strstr(pcmd, "%MB")) != NULL)
  516. {
  517. strncpy(p, newmail_folder->foldername, strlen(newmail_folder->foldername));
  518. }
  519. pcmd = g_strdup_printf("%s &", pcmd);
  520. #ifdef DEBUG
  521. printf("execute popup command '%s'\n",pcmd);
  522. #endif
  523. argv[2] = pcmd;
  524. pid = vfork();
  525. if(pid == (pid_t) 0)
  526. {
  527. for(curpos = 3; curpos < 255; curpos++)
  528. close(curpos);
  529. execv("/bin/sh", argv);
  530. }
  531. #ifdef DEBUG
  532. else
  533. {
  534. printf("master control program still active, all done.\n");
  535. }
  536. #endif
  537. }
  538. /* play alertfile if selected */
  539. if(alertfile != NULL)
  540. {
  541. #ifdef DEBUG
  542. printf("play alert file '%s'\n", alertfile);
  543. #endif
  544. /* warning: crazy rumgetuedel ahead! */
  545. if(xmms_remote_is_shuffle(mailnotify.xmms_session))
  546. {
  547. xmms_remote_toggle_shuffle(mailnotify.xmms_session);
  548. toggleshuffle = TRUE;
  549. }
  550. saved_position = xmms_remote_get_playlist_pos(mailnotify.xmms_session);
  551. saved_offset = xmms_remote_get_output_time(mailnotify.xmms_session);
  552. afpos = xmms_remote_get_playlist_length(mailnotify.xmms_session);
  553. xmms_remote_playlist(mailnotify.xmms_session, list, 1, TRUE);
  554. if(xmms_remote_get_playlist_length(mailnotify.xmms_session) == (afpos + 1))
  555. {
  556. #ifdef DEBUG
  557. printf("playing file %d", afpos);
  558. dummy = xmms_remote_get_playlist_file(mailnotify.xmms_session, afpos);
  559. printf("which is %s\n", dummy);
  560. #endif
  561. xmms_remote_set_playlist_pos(mailnotify.xmms_session, afpos);
  562. if(!xmms_remote_is_playing(mailnotify.xmms_session))
  563. {
  564. wasplaying = FALSE;
  565. xmms_remote_play(mailnotify.xmms_session);
  566. }
  567. curpos = xmms_remote_get_playlist_pos(mailnotify.xmms_session);
  568. xmms_usleep(100000);
  569. /* if crossfade output plugin is activated we need to do some tricks here */
  570. if(xfade_active)
  571. {
  572. printf("Warning! Xfade workaround not yet implemented!\nTurn off crossfade plugin or mailnotify wont work!\n");
  573. /* implement xfade workaround here.. */
  574. }
  575. do
  576. {
  577. xmms_usleep(10000);
  578. curpos = xmms_remote_get_playlist_pos(mailnotify.xmms_session);
  579. } while(curpos == afpos);
  580. #ifdef DEBUG
  581. printf("playing finished, deleting file from playlist\n");
  582. printf("and resetting to %d", saved_position);
  583. dummy = xmms_remote_get_playlist_file(mailnotify.xmms_session, saved_position);
  584. printf(" which is %s\n", dummy);
  585. #endif
  586. if(!wasplaying)
  587. xmms_remote_stop(mailnotify.xmms_session);
  588. xmms_remote_set_playlist_pos(mailnotify.xmms_session, saved_position);
  589. xmms_remote_playlist_delete(mailnotify.xmms_session, afpos);
  590. #ifdef CONTINUE_WHERE_INTERRUPTED
  591. if(wasplaying)
  592. xmms_remote_jump_to_time(mailnotify.xmms_session, saved_offset);
  593. #endif
  594. }
  595. else
  596. {
  597. printf("Enqueuing %s failed.\n", list[0]);
  598. }
  599. if(toggleshuffle)
  600. xmms_remote_toggle_shuffle(mailnotify.xmms_session);
  601. }
  602. g_free(pcmd);
  603. g_free(list);
  604. }
  605. void register_folders(void)
  606. {
  607. /* currently there is only one mailbox supported.. */
  608. strcpy(folders[0].foldername, mailboxname);
  609. fd = fopen(folders[0].foldername, "r");
  610. folders[0].filesize = bytes(folders[0].foldername);
  611. #ifdef DEBUG
  612. printf("Folder %s is %ld bytes in size.\n", folders[0].foldername, folders[0].filesize);
  613. #endif
  614. all_folders = 1;
  615. if (fd != NULL)
  616. fclose(fd);
  617. }
  618. void check_config(void)
  619. {
  620. if(mailboxname == NULL)
  621. get_default_folder();
  622. if(alertfile == NULL)
  623. alertfile = DEFAULT_ALERT_FILE;
  624. if(popup_command == NULL)
  625. popup_command = DEFAULT_POPUP_COMMAND;
  626. if(check_seconds <= 1)
  627. check_seconds = DEFAULT_INTERVAL;
  628. #ifdef DEBUG
  629. printf("Check Config:\n\tmailboxname = %s\n\talertfile = %s\n\tpopup_cmd = %s\n\tinterval = %d\n\txfade = %d\n", mailboxname, alertfile, popup_command, check_seconds, xfade_active);
  630. #endif
  631. }
  632. int read_sender(mailfile, nmfolder)
  633. FILE *mailfile;
  634. register struct folder *nmfolder;
  635. {
  636. register gchar *buffer;
  637. gchar *from_match = "From";
  638. regmatch_t pmatch[5];
  639. regex_t rbuf;
  640. buffer = g_malloc0(255 * sizeof(gchar *));
  641. while(!feof(mailfile) && (strlen(nmfolder->sender) < 3))
  642. {
  643. fgets(buffer, 255, mailfile);
  644. if(!strncmp(buffer, from_match, sizeof(from_match) ))
  645. {
  646. /** i like perl that much.. **/
  647. if(regcomp(&rbuf, "[[:blank:]<]\\(.*@[[:alnum:][:punct:]]*\\)[[:blank:]>]",0))
  648. {
  649. printf("Fatal: error compiling regular expression.\n");
  650. }
  651. if(!regexec(&rbuf, buffer, 2,pmatch,0 ))
  652. {
  653. memcpy(nmfolder->sender, buffer + pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so);
  654. break;
  655. }
  656. break;
  657. }
  658. }
  659. g_free(buffer);
  660. if(nmfolder->sender)
  661. return 1;
  662. else
  663. return 0;
  664. }
  665. /* end of file */