/* * Copyright (C) 1998 Nathan Neulinger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include "gtkyahoo.h" /* structure for holding a users status, used in this file only */ struct action { int type; int delay; char *command; char *sound; char *function; char *message; int last_executed; }; /* keep static, not using anywhere else */ static GHashTable *actionhash = NULL; /* quicky routine to create the hash */ static inline void action_hash_init(void) { if (!actionhash) { actionhash = g_hash_table_new((GHashFunc) gtkyahoo_hash, (GCompareFunc) gtkyahoo_hash_compare); } } /* allocate a new status structure */ static struct action *action_alloc(void) { struct action *action; action = (struct action *) calloc(1, sizeof(*action)); return action; } /* retrieve a pointer to a action */ static struct action *action_get(char *name) { struct action *action; char *tmpname; if (!name) return NULL; /* think i am not supposed to free this */ tmpname = strlower(name); action_hash_init(); action = (struct action *) g_hash_table_lookup(actionhash, (gpointer) tmpname); if (!action) { action = action_alloc(); g_hash_table_insert(actionhash, (gpointer) tmpname, (gpointer) action); DBG_Print("actions", "Creating and inserted new action (%s).\n", tmpname); } else { DBG_Print("actions", "Retrieved existing action (%s).\n", tmpname); } return action; } /* set an action type */ void action_set_type(char *name, int type) { struct action *action = action_get(name); action->type = type; DBG_Print("actions", "Set action type to (%d)\n", type); } /* set an action delay */ void action_set_delay(char *name, int delay) { struct action *action = action_get(name); action->delay = delay; DBG_Print("actions", "Set action delay to (%d)\n", delay); } /* set an action command */ void action_set_command(char *name, char *command) { struct action *action = action_get(name); if (action->command) { free(action->command); action->command = NULL; } if (command) { action->command = strdup(command); DBG_Print("actions", "Set action command to (%s)\n", command); } } /* set an action sound */ void action_set_sound(char *name, char *sound) { struct action *action = action_get(name); if (action->sound) { free(action->sound); action->sound = NULL; } if (sound) { action->sound = strdup(sound); DBG_Print("actions", "Set action sound to (%s)\n", sound); } } /* set an action sound */ void action_set_message(char *name, char *message) { struct action *action = action_get(name); if (action->message) { free(action->message); action->message = NULL; } if (message) { action->message = strdup(message); DBG_Print("actions", "Set action message to (%s)\n", message); } } /* Execute a particular action's command */ static void action_execute_command(struct action *tmp) { char *cmdsubst = NULL; int pipe_message = 0; char *message = 0; int pid = 0; if (tmp->type != ACTION_TYPE_COMMAND) { DBG_Print("actions", "\tNot a command type action.\n"); return; } if (tmp->command) { DBG_Print("actions", "\tExecuting Command: %s\n", tmp->command); cmdsubst = tmp->command; if ((pid = fork()) == 0) { FILE *fp; if (pipe_message && message) { if ((fp = popen(cmdsubst, "w"))) fprintf(fp, message); fclose(fp); } else system(cmdsubst); _exit(1); /* _exit() vs. exit() keeps everyone happy */ } } else { DBG_Print("actions", "\tNo Command Specified.\n"); } } /* execute a given action */ void action_execute(char *name) { struct action *tmp; int now = time(0); if (name) { DBG_Print("actions", "Executing action: %s\n", name); } tmp = action_get(name); if (!tmp) { DBG_Print("actions", "\tInvalid action: %s\n", name); return; } if (now - tmp->last_executed < tmp->delay) { DBG_Print("actions", "\tSkipping action due to delay.\n"); return; } else { tmp->last_executed = now; } if (tmp->type == ACTION_TYPE_COMMAND) { action_execute_command(tmp); } else if (tmp->type == ACTION_TYPE_SOUND) { play_sound(tmp->sound); } else if (tmp->type == ACTION_TYPE_DIALOG) { if (NULL != tmp->message) { char **msgs; msgs = malloc(2 * sizeof(char *)); msgs[0] = malloc(1000); msgs[1] = NULL; snprintf(msgs[0], 1000, tmp->message); create_alert_window("GTKYahoo: Notify", msgs, "Understood", FALSE); free(msgs[0]); free(msgs); } } }