#include #include #include #include #include #include #include #include #include #include #include #include #include "owl.h" static const char fileIdent[] = "$Id$"; void owl_function_noop(void) { return; } char *owl_function_command(char *cmdbuff) { owl_function_debugmsg("executing command: %s", cmdbuff); return owl_cmddict_execute(owl_global_get_cmddict(&g), owl_global_get_context(&g), cmdbuff); } void owl_function_command_norv(char *cmdbuff) { char *rv; rv=owl_function_command(cmdbuff); if (rv) owl_free(rv); } void owl_function_command_alias(char *alias_from, char *alias_to) { owl_cmddict_add_alias(owl_global_get_cmddict(&g), alias_from, alias_to); } owl_cmd *owl_function_get_cmd(char *name) { return owl_cmddict_find(owl_global_get_cmddict(&g), name); } void owl_function_show_commands() { owl_list l; owl_fmtext fm; owl_fmtext_init_null(&fm); owl_fmtext_append_bold(&fm, "Commands: "); owl_fmtext_append_normal(&fm, "(use 'show command ' for details)\n"); owl_cmddict_get_names(owl_global_get_cmddict(&g), &l); owl_fmtext_append_list(&fm, &l, "\n", owl_function_cmd_describe); owl_fmtext_append_normal(&fm, "\n"); owl_function_popless_fmtext(&fm); owl_cmddict_namelist_free(&l); owl_fmtext_free(&fm); } void owl_function_show_view(char *viewname) { owl_view *v; owl_fmtext fm; /* we only have the one view right now */ v=owl_global_get_current_view(&g); if (viewname && strcmp(viewname, owl_view_get_name(v))) { owl_function_error("No view named '%s'", viewname); return; } owl_fmtext_init_null(&fm); owl_view_to_fmtext(v, &fm); owl_function_popless_fmtext(&fm); owl_fmtext_free(&fm); } void owl_function_show_styles() { owl_list l; owl_fmtext fm; owl_fmtext_init_null(&fm); owl_fmtext_append_bold(&fm, "Styles:\n"); owl_global_get_style_names(&g, &l); owl_fmtext_append_list(&fm, &l, "\n", owl_function_style_describe); owl_fmtext_append_normal(&fm, "\n"); owl_function_popless_fmtext(&fm); owl_list_free_all(&l, owl_free); owl_fmtext_free(&fm); } char *owl_function_style_describe(void *name) { char *desc, *s; owl_style *style; style = owl_global_get_style_by_name(&g, name); if (style) { desc = owl_style_get_description(style); } else { desc = "???"; } s = owl_sprintf("%-20s - %s%s", name, 0==owl_style_validate(style)?"":"[INVALID] ", desc); return s; } char *owl_function_cmd_describe(void *name) { owl_cmd *cmd = owl_cmddict_find(owl_global_get_cmddict(&g), name); if (cmd) return owl_cmd_describe(cmd); else return(NULL); } void owl_function_show_command(char *name) { owl_function_help_for_command(name); } void owl_function_show_license() { char *text; text="" "Owl version " OWL_VERSION_STRING "\n" "Copyright (c) 2004 James Kretchmar. All rights reserved.\n" "\n" "Redistribution and use in source and binary forms, with or without\n" "modification, are permitted provided that the following conditions are\n" "met:\n" "\n" " * Redistributions of source code must retain the above copyright\n" " notice, this list of conditions and the following disclaimer.\n" "\n" " * Redistributions in binary form must reproduce the above copyright\n" " notice, this list of conditions and the following disclaimer in\n" " the documentation and/or other materials provided with the\n" " distribution.\n" "\n" " * Redistributions in any form must be accompanied by information on\n" " how to obtain complete source code for the Owl software and any\n" " accompanying software that uses the Owl software. The source code\n" " must either be included in the distribution or be available for no\n" " more than the cost of distribution plus a nominal fee, and must be\n" " freely redistributable under reasonable conditions. For an\n" " executable file, complete source code means the source code for\n" " all modules it contains. It does not include source code for\n" " modules or files that typically accompany the major components of\n" " the operating system on which the executable file runs.\n" "\n" "THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n" "IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n" "WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR\n" "NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE\n" "LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n" "CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n" "SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n" "BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n" "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n" "OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN\n" "IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"; owl_function_popless_text(text); } /* Add the given message to Owl's internal queue. If displayoutgoing * is disabled, the message is NOT added to any internal queue, -1 is * returned and THE CALLER IS EXPECTED TO FREE THE GIVEN MESSAGE. * Otherwise 0 is returned and the caller need do nothing more */ int owl_function_add_message(owl_message *m) { /* if displayoutgoing is disabled, nuke the message and move on */ if (! owl_global_is_displayoutgoing(&g)) { return(-1); } /* add it to the global list and current view */ owl_messagelist_append_element(owl_global_get_msglist(&g), m); owl_view_consider_message(owl_global_get_current_view(&g), m); /* do followlast if necessary */ if (owl_global_should_followlast(&g)) owl_function_lastmsg_noredisplay(); /* redisplay etc. */ owl_mainwin_redisplay(owl_global_get_mainwin(&g)); if (owl_popwin_is_active(owl_global_get_popwin(&g))) { owl_popwin_refresh(owl_global_get_popwin(&g)); } wnoutrefresh(owl_global_get_curs_recwin(&g)); owl_global_set_needrefresh(&g); return(0); } /* Create an admin message, append it to the global list of messages * and redisplay if necessary. */ void owl_function_adminmsg(char *header, char *body) { owl_message *m; m=owl_malloc(sizeof(owl_message)); owl_message_create_admin(m, header, body); /* add it to the global list and current view */ owl_messagelist_append_element(owl_global_get_msglist(&g), m); owl_view_consider_message(owl_global_get_current_view(&g), m); /* do followlast if necessary */ if (owl_global_should_followlast(&g)) owl_function_lastmsg_noredisplay(); /* redisplay etc. */ owl_mainwin_redisplay(owl_global_get_mainwin(&g)); if (owl_popwin_is_active(owl_global_get_popwin(&g))) { owl_popwin_refresh(owl_global_get_popwin(&g)); } wnoutrefresh(owl_global_get_curs_recwin(&g)); owl_global_set_needrefresh(&g); } /* Create an outgoing zephyr message and return a pointer to it. Does * not put it on the global queue, use owl_function_add_message() for * that. */ owl_message *owl_function_make_outgoing_zephyr(char *body, char *zwriteline, char *zsig) { owl_message *m; owl_zwrite z; /* create a zwrite for the purpose of filling in other message fields */ owl_zwrite_create_from_line(&z, zwriteline); /* create the message */ m=owl_malloc(sizeof(owl_message)); owl_message_create_from_zwriteline(m, zwriteline, body, zsig); owl_zwrite_free(&z); return(m); } /* Create an outgoing AIM message, returns a pointer to the created * message or NULL if we're not logged into AIM (and thus unable to * create the message). Does not put it on the global queue. Use * owl_function_add_message() for that . */ owl_message *owl_function_make_outgoing_aim(char *body, char *to) { owl_message *m; /* error if we're not logged into aim */ if (!owl_global_is_aimloggedin(&g)) return(NULL); m=owl_malloc(sizeof(owl_message)); owl_message_create_aim(m, owl_global_get_aim_screenname(&g), to, body, OWL_MESSAGE_DIRECTION_OUT, 0); return(m); } /* Create an outgoing loopback message and return a pointer to it. * Does not append it to the global queue, use * owl_function_add_message() for that. */ owl_message *owl_function_make_outgoing_loopback(char *body) { owl_message *m; /* create the message */ m=owl_malloc(sizeof(owl_message)); owl_message_create_loopback(m, body); owl_message_set_direction_out(m); return(m); } void owl_function_zwrite_setup(char *line) { owl_editwin *e; char buff[1024]; owl_zwrite z; int ret; /* check the arguments */ ret=owl_zwrite_create_from_line(&z, line); if (ret) { owl_function_error("Error in zwrite arugments"); owl_zwrite_free(&z); return; } /* send a ping if necessary */ if (owl_global_is_txping(&g)) { owl_zwrite_send_ping(&z); } owl_zwrite_free(&z); /* create and setup the editwin */ e=owl_global_get_typwin(&g); owl_editwin_new_style(e, OWL_EDITWIN_STYLE_MULTILINE, owl_global_get_msg_history(&g)); if (!owl_global_get_lockout_ctrld(&g)) { owl_function_makemsg("Type your zephyr below. End with ^D or a dot on a line by itself. ^C will quit."); } else { owl_function_makemsg("Type your zephyr below. End with a dot on a line by itself. ^C will quit."); } owl_editwin_clear(e); owl_editwin_set_dotsend(e); strcpy(buff, "----> "); strcat(buff, line); strcat(buff, "\n"); owl_editwin_set_locktext(e, buff); /* make it active */ owl_global_set_typwin_active(&g); owl_global_set_buffercommand(&g, line); owl_global_set_buffercallback(&g, &owl_callback_zwrite); } void owl_function_aimwrite_setup(char *line) { owl_editwin *e; char buff[1024]; /* check the arguments */ /* create and setup the editwin */ e=owl_global_get_typwin(&g); owl_editwin_new_style(e, OWL_EDITWIN_STYLE_MULTILINE, owl_global_get_msg_history(&g)); if (!owl_global_get_lockout_ctrld(&g)) { owl_function_makemsg("Type your message below. End with ^D or a dot on a line by itself. ^C will quit."); } else { owl_function_makemsg("Type your message below. End with a dot on a line by itself. ^C will quit."); } owl_editwin_clear(e); owl_editwin_set_dotsend(e); strcpy(buff, "----> "); strcat(buff, line); strcat(buff, "\n"); owl_editwin_set_locktext(e, buff); /* make it active */ owl_global_set_typwin_active(&g); owl_global_set_buffercommand(&g, line); owl_global_set_buffercallback(&g, &owl_callback_aimwrite); } void owl_function_loopwrite_setup() { owl_editwin *e; /* create and setup the editwin */ e=owl_global_get_typwin(&g); owl_editwin_new_style(e, OWL_EDITWIN_STYLE_MULTILINE, owl_global_get_msg_history(&g)); if (!owl_global_get_lockout_ctrld(&g)) { owl_function_makemsg("Type your message below. End with ^D or a dot on a line by itself. ^C will quit."); } else { owl_function_makemsg("Type your message below. End with a dot on a line by itself. ^C will quit."); } owl_editwin_clear(e); owl_editwin_set_dotsend(e); owl_editwin_set_locktext(e, "----> loopwrite\n"); /* make it active */ owl_global_set_typwin_active(&g); owl_global_set_buffercommand(&g, "loopwrite"); owl_global_set_buffercallback(&g, &owl_callback_loopwrite); } void owl_callback_zwrite(owl_editwin *e) { owl_function_zwrite(owl_editwin_get_command(e), owl_editwin_get_text(e)); } /* send, log and display an outgoing zephyr. If 'msg' is NULL * the message is expected to be set from the zwrite line itself */ void owl_function_zwrite(char *line, char *msg) { owl_zwrite z; char *mymsg; owl_message *m; /* create the zwrite and send the message */ owl_zwrite_create_from_line(&z, line); if (msg) { owl_zwrite_set_message(&z, msg); } owl_zwrite_send_message(&z); owl_function_makemsg("Waiting for ack..."); /* If it's personal */ if (owl_zwrite_is_personal(&z)) { /* create the outgoing message */ mymsg=owl_zwrite_get_message(&z); m=owl_function_make_outgoing_zephyr(mymsg, line, owl_zwrite_get_zsig(&z)); if (m) { /* log it */ owl_log_message(m); /* add it or nuke it */ if (owl_global_is_displayoutgoing(&g)) { owl_function_add_message(m); } else { owl_message_free(m); } } else { owl_function_error("Could not create outgoing zephyr message"); } } /* free the zwrite */ owl_zwrite_free(&z); } /* send, log and display an outgoing zcrypt zephyr. If 'msg' is NULL * the message is expected to be set from the zwrite line itself */ void owl_function_zcrypt(char *line, char *msg) { owl_zwrite z; char *mymsg; char *cryptmsg; owl_message *m; #ifdef OWL_ENABLE_ZCRYPT int ret; #endif /* create the zwrite and send the message */ owl_zwrite_create_from_line(&z, line); if (msg) { owl_zwrite_set_message(&z, msg); } mymsg=owl_zwrite_get_message(&z); #ifdef OWL_ENABLE_ZCRYPT cryptmsg=owl_malloc(strlen(mymsg)*4); ret=owl_zcrypt_encrypt(cryptmsg, mymsg, owl_zwrite_get_class(&z), owl_zwrite_get_instance(&z)); if (ret) { owl_function_error("Error in zcrypt, possibly no key found. Message not sent."); owl_function_beep(); owl_free(cryptmsg); return; } #else cryptmsg=owl_strdup(mymsg); #endif owl_zwrite_set_message(&z, cryptmsg); owl_zwrite_set_opcode(&z, "crypt"); mymsg=cryptmsg; owl_zwrite_send_message(&z); owl_function_makemsg("Waiting for ack..."); /* If it's personal */ if (owl_zwrite_is_personal(&z)) { /* create the outgoing message */ mymsg=owl_zwrite_get_message(&z); m=owl_function_make_outgoing_zephyr(mymsg, line, owl_zwrite_get_zsig(&z)); if (m) { /* log it */ owl_log_message(m); /* add it or nuke it */ if (owl_global_is_displayoutgoing(&g)) { owl_function_add_message(m); } else { owl_message_free(m); } } else { owl_function_error("Could not create outgoing zephyr message"); } } /* free the zwrite */ owl_free(cryptmsg); owl_zwrite_free(&z); } void owl_callback_aimwrite(owl_editwin *e) { owl_function_aimwrite(owl_editwin_get_command(e), owl_editwin_get_text(e)); } void owl_function_aimwrite(char *line, char *msg) { int ret; char *to, *format_msg; owl_message *m; to = line + 9; /* make a formatted copy of the message */ format_msg=owl_strdup(msg); owl_text_wordunwrap(format_msg); /* send the message */ ret=owl_aim_send_im(to, format_msg); if (!ret) { owl_function_makemsg("AIM message sent."); } else { owl_function_error("Could not send AIM message."); } /* create the outgoing message */ m=owl_function_make_outgoing_aim(msg, to); if (m) { /* log it */ owl_log_message(m); /* display it or nuke it */ if (owl_global_is_displayoutgoing(&g)) { owl_function_add_message(m); } else { owl_message_free(m); } } else { owl_function_error("Could not create outgoing AIM message"); } owl_free(format_msg); } void owl_function_send_aimawymsg(char *to, char *msg) { int ret; char *format_msg; owl_message *m; /* make a formatted copy of the message */ format_msg=owl_strdup(msg); owl_text_wordunwrap(format_msg); /* send the message */ ret=owl_aim_send_awaymsg(to, format_msg); if (!ret) { /* owl_function_makemsg("AIM message sent."); */ } else { owl_function_error("Could not send AIM message."); } /* create the message */ m=owl_function_make_outgoing_aim(msg, to); if (m) { /* log it */ owl_log_message(m); /* display it or nuke it */ if (owl_global_is_displayoutgoing(&g)) { owl_function_add_message(m); } else { owl_message_free(m); } } else { owl_function_error("Could not create AIM message"); } owl_free(format_msg); } void owl_callback_loopwrite(owl_editwin *e) { owl_function_loopwrite(owl_editwin_get_text(e)); } void owl_function_loopwrite(char *msg) { owl_message *min, *mout; /* create a message and put it on the message queue. This simulates * an incoming message */ min=owl_malloc(sizeof(owl_message)); owl_message_create_loopback(min, msg); owl_message_set_direction_in(min); owl_global_messagequeue_addmsg(&g, min); mout=owl_function_make_outgoing_loopback(msg); owl_log_message(mout); if (owl_global_is_displayoutgoing(&g)) { owl_function_add_message(mout); } else { owl_message_free(mout); } /* fake a makemsg */ owl_function_makemsg("loopback message sent"); } /* If filter is non-null, looks for the next message matching * that filter. If skip_deleted, skips any deleted messages. * If last_if_none, will stop at the last message in the view * if no matching messages are found. */ void owl_function_nextmsg_full(char *filter, int skip_deleted, int last_if_none) { int curmsg, i, viewsize, found; owl_view *v; owl_filter *f = NULL; owl_message *m; v=owl_global_get_current_view(&g); if (filter) { f=owl_global_get_filter(&g, filter); if (!f) { owl_function_error("No %s filter defined", filter); return; } } curmsg=owl_global_get_curmsg(&g); viewsize=owl_view_get_size(v); found=0; /* just check to make sure we're in bounds... */ if (curmsg>viewsize-1) curmsg=viewsize-1; if (curmsg<0) curmsg=0; for (i=curmsg+1; iowl_view_get_size(v)-1) i=owl_view_get_size(v)-1; if (!found) { owl_function_makemsg("already at last%s message%s%s", skip_deleted?" non-deleted":"", filter?" in ":"", filter?filter:""); /* if (!skip_deleted) owl_function_beep(); */ } if (last_if_none || found) { owl_global_set_curmsg(&g, i); owl_function_calculate_topmsg(OWL_DIRECTION_DOWNWARDS); owl_mainwin_redisplay(owl_global_get_mainwin(&g)); owl_global_set_direction_downwards(&g); } } void owl_function_prevmsg_full(char *filter, int skip_deleted, int first_if_none) { int curmsg, i, viewsize, found; owl_view *v; owl_filter *f = NULL; owl_message *m; v=owl_global_get_current_view(&g); if (filter) { f=owl_global_get_filter(&g, filter); if (!f) { owl_function_error("No %s filter defined", filter); return; } } curmsg=owl_global_get_curmsg(&g); viewsize=owl_view_get_size(v); found=0; /* just check to make sure we're in bounds... */ if (curmsg<0) curmsg=0; for (i=curmsg-1; i>=0; i--) { m=owl_view_get_element(v, i); if (skip_deleted && owl_message_is_delete(m)) continue; if (f && !owl_filter_message_match(f, m)) continue; found = 1; break; } if (i<0) i=0; if (!found) { owl_function_makemsg("already at first%s message%s%s", skip_deleted?" non-deleted":"", filter?" in ":"", filter?filter:""); /* if (!skip_deleted) owl_function_beep(); */ } if (first_if_none || found) { owl_global_set_curmsg(&g, i); owl_function_calculate_topmsg(OWL_DIRECTION_UPWARDS); owl_mainwin_redisplay(owl_global_get_mainwin(&g)); owl_global_set_direction_upwards(&g); } } void owl_function_nextmsg() { owl_function_nextmsg_full(NULL, 0, 1); } void owl_function_prevmsg() { owl_function_prevmsg_full(NULL, 0, 1); } void owl_function_nextmsg_notdeleted() { owl_function_nextmsg_full(NULL, 1, 1); } void owl_function_prevmsg_notdeleted() { owl_function_prevmsg_full(NULL, 1, 1); } void owl_function_nextmsg_personal() { owl_function_nextmsg_full("personal", 0, 0); } void owl_function_prevmsg_personal() { owl_function_prevmsg_full("personal", 0, 0); } /* if move_after is 1, moves after the delete */ void owl_function_deletecur(int move_after) { int curmsg; owl_view *v; v=owl_global_get_current_view(&g); /* bail if there's no current message */ if (owl_view_get_size(v) < 1) { owl_function_error("No current message to delete"); return; } /* mark the message for deletion */ curmsg=owl_global_get_curmsg(&g); owl_view_delete_element(v, curmsg); if (move_after) { /* move the poiner in the appropriate direction * to the next undeleted msg */ if (owl_global_get_direction(&g)==OWL_DIRECTION_UPWARDS) { owl_function_prevmsg_notdeleted(); } else { owl_function_nextmsg_notdeleted(); } } } void owl_function_undeletecur(int move_after) { int curmsg; owl_view *v; v=owl_global_get_current_view(&g); if (owl_view_get_size(v) < 1) { owl_function_error("No current message to undelete"); return; } curmsg=owl_global_get_curmsg(&g); owl_view_undelete_element(v, curmsg); if (move_after) { if (owl_global_get_direction(&g)==OWL_DIRECTION_UPWARDS) { if (curmsg>0) { owl_function_prevmsg(); } else { owl_function_nextmsg(); } } else { owl_function_nextmsg(); } } owl_mainwin_redisplay(owl_global_get_mainwin(&g)); } void owl_function_expunge() { int curmsg; owl_message *m; owl_messagelist *ml; owl_view *v; int lastmsgid=0; curmsg=owl_global_get_curmsg(&g); v=owl_global_get_current_view(&g); ml=owl_global_get_msglist(&g); m=owl_view_get_element(v, curmsg); if (m) lastmsgid = owl_message_get_id(m); /* expunge the message list */ owl_messagelist_expunge(ml); /* update all views (we only have one right now) */ owl_view_recalculate(v); /* find where the new position should be (as close as possible to where we last where) */ curmsg = owl_view_get_nearest_to_msgid(v, lastmsgid); if (curmsg>owl_view_get_size(v)-1) curmsg = owl_view_get_size(v)-1; if (curmsg<0) curmsg = 0; owl_global_set_curmsg(&g, curmsg); owl_function_calculate_topmsg(OWL_DIRECTION_NONE); /* if there are no messages set the direction to down in case we delete everything upwards */ owl_global_set_direction_downwards(&g); owl_function_makemsg("Messages expunged"); owl_mainwin_redisplay(owl_global_get_mainwin(&g)); } void owl_function_firstmsg() { owl_global_set_curmsg(&g, 0); owl_global_set_topmsg(&g, 0); owl_mainwin_redisplay(owl_global_get_mainwin(&g)); owl_global_set_direction_downwards(&g); } void owl_function_lastmsg_noredisplay() { int oldcurmsg, curmsg; owl_view *v; v=owl_global_get_current_view(&g); oldcurmsg=owl_global_get_curmsg(&g); curmsg=owl_view_get_size(v)-1; if (curmsg<0) curmsg=0; owl_global_set_curmsg(&g, curmsg); if (oldcurmsg < curmsg) { owl_function_calculate_topmsg(OWL_DIRECTION_DOWNWARDS); } else if (curmsg=10) { owl_global_set_rightshift(&g, shift-10); owl_mainwin_redisplay(owl_global_get_mainwin(&g)); owl_global_set_needrefresh(&g); } else { owl_function_beep(); owl_function_makemsg("Already full left"); } } void owl_function_unsuball() { unsuball(); owl_function_makemsg("Unsubscribed from all messages."); } /* Load zephyr subscriptions from the named 'file' and load zephyr's * default subscriptions as well. An error message is printed if * 'file' can't be opened or if zephyr reports an error in * subscribing. * * If 'file' is NULL, this look for the default filename * $HOME/.zephyr.subs. If the file can not be opened in this case * only, no error message is printed. */ void owl_function_loadsubs(char *file) { int ret, ret2; char *foo; if (file==NULL) { ret=owl_zephyr_loadsubs(NULL, 0); } else { ret=owl_zephyr_loadsubs(file, 1); } /* for backwards compatibility for now */ ret2=owl_zephyr_loaddefaultsubs(); if (!owl_context_is_interactive(owl_global_get_context(&g))) return; foo=file?file:"file"; if (ret==0 && ret2==0) { if (!file) { owl_function_makemsg("Subscribed to messages."); } else { owl_function_makemsg("Subscribed to messages from %s", file); } } else if (ret==-1) { owl_function_error("Could not read %s", foo); } else { owl_function_error("Error subscribing to messages"); } } void owl_function_loadloginsubs(char *file) { int ret; ret=owl_zephyr_loadloginsubs(file); if (!owl_context_is_interactive(owl_global_get_context(&g))) return; if (ret==0) { owl_function_makemsg("Subscribed to login messages from file."); } else if (ret==-1) { owl_function_error("Could not open file for login subscriptions."); } else { owl_function_error("Error subscribing to login messages from file."); } } void owl_callback_aimlogin(owl_editwin *e) { owl_function_aimlogin(owl_editwin_get_command(e), owl_editwin_get_text(e)); } void owl_function_aimlogin(char *user, char *passwd) { int ret; /* clear the buddylist */ owl_buddylist_clear(owl_global_get_buddylist(&g)); /* try to login */ ret=owl_aim_login(user, passwd); if (ret) owl_function_makemsg("Warning: login for %s failed.\n", user); } void owl_function_suspend() { endwin(); printf("\n"); kill(getpid(), SIGSTOP); /* resize to reinitialize all the windows when we come back */ owl_command_resize(); } void owl_function_zaway_toggle() { if (!owl_global_is_zaway(&g)) { owl_global_set_zaway_msg(&g, owl_global_get_zaway_msg_default(&g)); owl_function_zaway_on(); } else { owl_function_zaway_off(); } } void owl_function_zaway_on() { owl_global_set_zaway_on(&g); owl_function_makemsg("zaway set (%s)", owl_global_get_zaway_msg(&g)); } void owl_function_zaway_off() { owl_global_set_zaway_off(&g); owl_function_makemsg("zaway off"); } void owl_function_aaway_toggle() { if (!owl_global_is_aaway(&g)) { owl_global_set_aaway_msg(&g, owl_global_get_aaway_msg_default(&g)); owl_function_aaway_on(); } else { owl_function_aaway_off(); } } void owl_function_aaway_on() { owl_global_set_aaway_on(&g); /* owl_aim_set_awaymsg(owl_global_get_zaway_msg(&g)); */ owl_function_makemsg("AIM away set (%s)", owl_global_get_aaway_msg(&g)); } void owl_function_aaway_off() { owl_global_set_aaway_off(&g); /* owl_aim_set_awaymsg(""); */ owl_function_makemsg("AIM away off"); } void owl_function_quit() { char *ret; /* zlog out if we need to */ if (owl_global_is_shutdownlogout(&g)) { owl_zephyr_zlog_out(); } /* execute the commands in shutdown */ ret = owl_perlconfig_execute("BarnOwl::Hooks::shutdown();"); if (ret) owl_free(ret); /* signal our child process, if any */ if (owl_global_get_newmsgproc_pid(&g)) { kill(owl_global_get_newmsgproc_pid(&g), SIGHUP); } /* Quit zephyr */ owl_zephyr_shutdown(); /* Quit AIM */ if (owl_global_is_aimloggedin(&g)) { owl_aim_logout(); } /* done with curses */ endwin(); /* restore terminal settings */ tcsetattr(0, TCSAFLUSH, owl_global_get_startup_tio(&g)); owl_function_debugmsg("Quitting Owl"); exit(0); } void owl_function_openurl() { /* visit the first url in the current message */ owl_message *m; owl_view *v; char *ptr1, *ptr2, *text, url[LINE], tmpbuff[LINE]; int webbrowser; webbrowser = owl_global_get_webbrowser(&g); if (webbrowser < 0 || webbrowser == OWL_WEBBROWSER_NONE) { owl_function_error("No browser selected"); return; } v=owl_global_get_current_view(&g); m=owl_view_get_element(v, owl_global_get_curmsg(&g)); if (!m || owl_view_get_size(v)==0) { owl_function_error("No current message selected"); return; } text=owl_message_get_text(m); /* First look for a good URL */ if ((ptr1=strstr(text, "http://"))!=NULL) { ptr2=strpbrk(ptr1, " \n\t"); if (ptr2) { strncpy(url, ptr1, ptr2-ptr1+1); url[ptr2-ptr1+1]='\0'; } else { strcpy(url, ptr1); } /* if we had */ if (ptr1>text && ptr1[-1]=='<') { if (url[strlen(url)-1]=='>') { url[strlen(url)-1]='\0'; } } } else if ((ptr1=strstr(text, "https://"))!=NULL) { /* Look for an https URL */ ptr2=strpbrk(ptr1, " \n\t"); if (ptr2) { strncpy(url, ptr1, ptr2-ptr1+1); url[ptr2-ptr1+1]='\0'; } else { strcpy(url, ptr1); } /* if we had */ if (ptr1>text && ptr1[-1]=='<') { if (url[strlen(url)-1]=='>') { url[strlen(url)-1]='\0'; } } } else if ((ptr1=strstr(text, "www."))!=NULL) { /* if we can't find a real url look for www.something */ ptr2=strpbrk(ptr1, " \n\t"); if (ptr2) { strncpy(url, ptr1, ptr2-ptr1+1); url[ptr2-ptr1+1]='\0'; } else { strcpy(url, ptr1); } } else { owl_function_beep(); owl_function_error("Could not find URL to open."); return; } /* Make sure there aren't any quotes or \'s in the url */ for (ptr1 = url; *ptr1; ptr1++) { if (*ptr1 == '"' || *ptr1 == '\\') { owl_function_beep(); owl_function_error("URL contains invalid characters."); return; } } /* NOTE: There are potentially serious security issues here... */ /* open the page */ owl_function_makemsg("Opening %s", url); if (webbrowser == OWL_WEBBROWSER_NETSCAPE) { snprintf(tmpbuff, LINE, "netscape -remote \"openURL(%s)\" > /dev/null 2> /dev/null", url); system(tmpbuff); } else if (webbrowser == OWL_WEBBROWSER_GALEON) { snprintf(tmpbuff, LINE, "galeon \"%s\" > /dev/null 2> /dev/null &", url); system(tmpbuff); } else if (webbrowser == OWL_WEBBROWSER_OPERA) { snprintf(tmpbuff, LINE, "opera \"%s\" > /dev/null 2> /dev/null &", url); system(tmpbuff); } } void owl_function_calculate_topmsg(int direction) { int recwinlines, topmsg, curmsg; owl_view *v; v=owl_global_get_current_view(&g); curmsg=owl_global_get_curmsg(&g); topmsg=owl_global_get_topmsg(&g); recwinlines=owl_global_get_recwin_lines(&g); /* if (owl_view_get_size(v) < 1) { return; } */ switch (owl_global_get_scrollmode(&g)) { case OWL_SCROLLMODE_TOP: topmsg = owl_function_calculate_topmsg_top(direction, v, curmsg, topmsg, recwinlines); break; case OWL_SCROLLMODE_NEARTOP: topmsg = owl_function_calculate_topmsg_neartop(direction, v, curmsg, topmsg, recwinlines); break; case OWL_SCROLLMODE_CENTER: topmsg = owl_function_calculate_topmsg_center(direction, v, curmsg, topmsg, recwinlines); break; case OWL_SCROLLMODE_PAGED: topmsg = owl_function_calculate_topmsg_paged(direction, v, curmsg, topmsg, recwinlines, 0); break; case OWL_SCROLLMODE_PAGEDCENTER: topmsg = owl_function_calculate_topmsg_paged(direction, v, curmsg, topmsg, recwinlines, 1); break; case OWL_SCROLLMODE_NORMAL: default: topmsg = owl_function_calculate_topmsg_normal(direction, v, curmsg, topmsg, recwinlines); } owl_function_debugmsg("Calculated a topmsg of %i", topmsg); owl_global_set_topmsg(&g, topmsg); } /* Returns what the new topmsg should be. * Passed the last direction of movement, * the current view, * the current message number in the view, * the top message currently being displayed, * and the number of lines in the recwin. */ int owl_function_calculate_topmsg_top(int direction, owl_view *v, int curmsg, int topmsg, int recwinlines) { return(curmsg); } int owl_function_calculate_topmsg_neartop(int direction, owl_view *v, int curmsg, int topmsg, int recwinlines) { if (curmsg>0 && (owl_message_get_numlines(owl_view_get_element(v, curmsg-1)) < recwinlines/2)) { return(curmsg-1); } else { return(curmsg); } } int owl_function_calculate_topmsg_center(int direction, owl_view *v, int curmsg, int topmsg, int recwinlines) { int i, last, lines; last = curmsg; lines = 0; for (i=curmsg-1; i>=0; i--) { lines += owl_message_get_numlines(owl_view_get_element(v, i)); if (lines > recwinlines/2) break; last = i; } return(last); } int owl_function_calculate_topmsg_paged(int direction, owl_view *v, int curmsg, int topmsg, int recwinlines, int center_on_page) { int i, last, lines, savey; /* If we're off the top of the screen, scroll up such that the * curmsg is near the botton of the screen. */ if (curmsg < topmsg) { last = curmsg; lines = 0; for (i=curmsg; i>=0; i--) { lines += owl_message_get_numlines(owl_view_get_element(v, i)); if (lines > recwinlines) break; last = i; } if (center_on_page) { return(owl_function_calculate_topmsg_center(direction, v, curmsg, 0, recwinlines)); } else { return(last); } } /* Find number of lines from top to bottom of curmsg (store in savey) */ savey=0; for (i=topmsg; i<=curmsg; i++) { savey+=owl_message_get_numlines(owl_view_get_element(v, i)); } /* if we're off the bottom of the screen, scroll down */ if (savey > recwinlines) { if (center_on_page) { return(owl_function_calculate_topmsg_center(direction, v, curmsg, 0, recwinlines)); } else { return(curmsg); } } /* else just stay as we are... */ return(topmsg); } int owl_function_calculate_topmsg_normal(int direction, owl_view *v, int curmsg, int topmsg, int recwinlines) { int savey, j, i, foo, y; if (curmsg<0) return(topmsg); /* If we're off the top of the screen then center */ if (curmsg recwinlines) { topmsg=curmsg; savey=owl_message_get_numlines(owl_view_get_element(v, i)); direction=OWL_DIRECTION_UPWARDS; } /* If our bottom line is less than 1/4 down the screen then scroll up */ if (direction == OWL_DIRECTION_UPWARDS || direction == OWL_DIRECTION_NONE) { if (savey < (recwinlines / 4)) { y=0; for (j=curmsg; j>=0; j--) { foo=owl_message_get_numlines(owl_view_get_element(v, j)); /* will we run the curmsg off the screen? */ if ((foo+y) >= recwinlines) { j++; if (j>curmsg) j=curmsg; break; } /* have saved 1/2 the screen space? */ y+=foo; if (y > (recwinlines / 2)) break; } if (j<0) j=0; return(j); } } if (direction == OWL_DIRECTION_DOWNWARDS || direction == OWL_DIRECTION_NONE) { /* If curmsg bottom line is more than 3/4 down the screen then scroll down */ if (savey > ((recwinlines * 3)/4)) { y=0; /* count lines from the top until we can save 1/2 the screen size */ for (j=topmsg; j (recwinlines / 2)) break; } if (j==curmsg) { j--; } return(j+1); } } return(topmsg); } void owl_function_resize() { owl_global_set_resize_pending(&g); } void owl_function_run_buffercommand() { owl_editwin_do_callback(owl_global_get_typwin(&g)); } void owl_function_debugmsg(char *fmt, ...) { FILE *file; time_t now; char buff1[LINE], buff2[LINE]; va_list ap; va_start(ap, fmt); if (!owl_global_is_debug_fast(&g)) return; file=fopen(owl_global_get_debug_file(&g), "a"); if (!file) return; now=time(NULL); strcpy(buff1, ctime(&now)); buff1[strlen(buff1)-1]='\0'; owl_global_get_runtime_string(&g, buff2); fprintf(file, "[%i - %s - %s]: ", (int) getpid(), buff1, buff2); vfprintf(file, fmt, ap); fprintf(file, "\n"); fclose(file); va_end(ap); } void owl_function_refresh() { owl_function_resize(); } void owl_function_beep() { if (owl_global_is_bell(&g)) { beep(); owl_global_set_needrefresh(&g); /* do we really need this? */ } } void owl_function_subscribe(char *class, char *inst, char *recip) { int ret; ret=owl_zephyr_sub(class, inst, recip); if (ret) { owl_function_error("Error subscribing."); } else { owl_function_makemsg("Subscribed."); } } void owl_function_unsubscribe(char *class, char *inst, char *recip) { int ret; ret=owl_zephyr_unsub(class, inst, recip); if (ret) { owl_function_error("Error subscribing."); } else { owl_function_makemsg("Unsubscribed."); } } void owl_function_set_cursor(WINDOW *win) { wnoutrefresh(win); } void owl_function_full_redisplay() { redrawwin(owl_global_get_curs_recwin(&g)); redrawwin(owl_global_get_curs_sepwin(&g)); // Work around curses segfualts with windows off the screen if (g.lines >= owl_global_get_typwin_lines(&g)+2) redrawwin(owl_global_get_curs_typwin(&g)); if (g.lines >= 2) redrawwin(owl_global_get_curs_msgwin(&g)); wnoutrefresh(owl_global_get_curs_recwin(&g)); wnoutrefresh(owl_global_get_curs_sepwin(&g)); wnoutrefresh(owl_global_get_curs_typwin(&g)); wnoutrefresh(owl_global_get_curs_msgwin(&g)); sepbar(""); owl_function_makemsg(""); owl_global_set_needrefresh(&g); } void owl_function_popless_text(char *text) { owl_popwin *pw; owl_viewwin *v; pw=owl_global_get_popwin(&g); v=owl_global_get_viewwin(&g); owl_popwin_up(pw); owl_viewwin_init_text(v, owl_popwin_get_curswin(pw), owl_popwin_get_lines(pw), owl_popwin_get_cols(pw), text); owl_popwin_refresh(pw); owl_viewwin_redisplay(v, 0); owl_global_set_needrefresh(&g); } void owl_function_popless_fmtext(owl_fmtext *fm) { owl_popwin *pw; owl_viewwin *v; pw=owl_global_get_popwin(&g); v=owl_global_get_viewwin(&g); owl_popwin_up(pw); owl_viewwin_init_fmtext(v, owl_popwin_get_curswin(pw), owl_popwin_get_lines(pw), owl_popwin_get_cols(pw), fm); owl_popwin_refresh(pw); owl_viewwin_redisplay(v, 0); owl_global_set_needrefresh(&g); } void owl_function_popless_file(char *filename) { owl_fmtext fm; FILE *file; char buff[1024]; file=fopen(filename, "r"); if (!file) { owl_function_error("Could not open file: %s", filename); return; } owl_fmtext_init_null(&fm); while (fgets(buff, 1024, file)) { owl_fmtext_append_normal(&fm, buff); /* owl_fmtext_append_normal(&fm, "\n"); */ } owl_function_popless_fmtext(&fm); owl_fmtext_free(&fm); fclose(file); } void owl_function_about() { char buff[5000]; sprintf(buff, "This is owl version %s\n", OWL_VERSION_STRING); strcat(buff, "\nOwl was written by James Kretchmar at the Massachusetts\n"); strcat(buff, "Institute of Technology. The first version, 0.5, was\n"); strcat(buff, "released in March 2002.\n"); strcat(buff, "\n"); strcat(buff, "The name 'owl' was chosen in reference to the owls in the\n"); strcat(buff, "Harry Potter novels, who are tasked with carrying messages\n"); strcat(buff, "between Witches and Wizards.\n"); strcat(buff, "\n"); strcat(buff, "Copyright 2002 Massachusetts Institute of Technology\n"); strcat(buff, "\n"); strcat(buff, "Permission to use, copy, modify, and distribute this\n"); strcat(buff, "software and its documentation for any purpose and without\n"); strcat(buff, "fee is hereby granted, provided that the above copyright\n"); strcat(buff, "notice and this permission notice appear in all copies\n"); strcat(buff, "and in supporting documentation. No representation is\n"); strcat(buff, "made about the suitability of this software for any\n"); strcat(buff, "purpose. It is provided \"as is\" without express\n"); strcat(buff, "or implied warranty.\n"); owl_function_popless_text(buff); } void owl_function_info() { owl_message *m; owl_fmtext fm, attrfm; char buff[10000]; owl_view *v; #ifdef HAVE_LIBZEPHYR ZNotice_t *n; #endif owl_fmtext_init_null(&fm); v=owl_global_get_current_view(&g); m=owl_view_get_element(v, owl_global_get_curmsg(&g)); if (!m || owl_view_get_size(v)==0) { owl_function_error("No message selected\n"); return; } owl_fmtext_append_bold(&fm, "General Information:\n"); owl_fmtext_append_normal(&fm, " Msg Id : "); sprintf(buff, "%i", owl_message_get_id(m)); owl_fmtext_append_normal(&fm, buff); owl_fmtext_append_normal(&fm, "\n"); owl_fmtext_append_normal(&fm, " Type : "); owl_fmtext_append_bold(&fm, owl_message_get_type(m)); owl_fmtext_append_normal(&fm, "\n"); if (owl_message_is_direction_in(m)) { owl_fmtext_append_normal(&fm, " Direction : in\n"); } else if (owl_message_is_direction_out(m)) { owl_fmtext_append_normal(&fm, " Direction : out\n"); } else if (owl_message_is_direction_none(m)) { owl_fmtext_append_normal(&fm, " Direction : none\n"); } else { owl_fmtext_append_normal(&fm, " Direction : unknown\n"); } owl_fmtext_append_normal(&fm, " Time : "); owl_fmtext_append_normal(&fm, owl_message_get_timestr(m)); owl_fmtext_append_normal(&fm, "\n"); if (!owl_message_is_type_admin(m)) { owl_fmtext_append_normal(&fm, " Sender : "); owl_fmtext_append_normal(&fm, owl_message_get_sender(m)); owl_fmtext_append_normal(&fm, "\n"); owl_fmtext_append_normal(&fm, " Recipient : "); owl_fmtext_append_normal(&fm, owl_message_get_recipient(m)); owl_fmtext_append_normal(&fm, "\n"); } if (owl_message_is_type_zephyr(m)) { owl_fmtext_append_bold(&fm, "\nZephyr Specific Information:\n"); owl_fmtext_append_normal(&fm, " Class : "); owl_fmtext_append_normal(&fm, owl_message_get_class(m)); owl_fmtext_append_normal(&fm, "\n"); owl_fmtext_append_normal(&fm, " Instance : "); owl_fmtext_append_normal(&fm, owl_message_get_instance(m)); owl_fmtext_append_normal(&fm, "\n"); owl_fmtext_append_normal(&fm, " Opcode : "); owl_fmtext_append_normal(&fm, owl_message_get_opcode(m)); owl_fmtext_append_normal(&fm, "\n"); owl_fmtext_append_normal(&fm, " Time : "); owl_fmtext_append_normal(&fm, owl_message_get_timestr(m)); owl_fmtext_append_normal(&fm, "\n"); #ifdef HAVE_LIBZEPHYR if (owl_message_is_direction_in(m)) { char *ptr, tmpbuff[1024]; int i, j, fields, len; n=owl_message_get_notice(m); if (!owl_message_is_pseudo(m)) { owl_fmtext_append_normal(&fm, " Kind : "); if (n->z_kind==UNSAFE) { owl_fmtext_append_normal(&fm, "UNSAFE\n"); } else if (n->z_kind==UNACKED) { owl_fmtext_append_normal(&fm, "UNACKED\n"); } else if (n->z_kind==ACKED) { owl_fmtext_append_normal(&fm, "ACKED\n"); } else if (n->z_kind==HMACK) { owl_fmtext_append_normal(&fm, "HMACK\n"); } else if (n->z_kind==HMCTL) { owl_fmtext_append_normal(&fm, "HMCTL\n"); } else if (n->z_kind==SERVACK) { owl_fmtext_append_normal(&fm, "SERVACK\n"); } else if (n->z_kind==SERVNAK) { owl_fmtext_append_normal(&fm, "SERVNACK\n"); } else if (n->z_kind==CLIENTACK) { owl_fmtext_append_normal(&fm, "CLIENTACK\n"); } else if (n->z_kind==STAT) { owl_fmtext_append_normal(&fm, "STAT\n"); } else { owl_fmtext_append_normal(&fm, "ILLEGAL VALUE\n"); } } owl_fmtext_append_normal(&fm, " Host : "); owl_fmtext_append_normal(&fm, owl_message_get_hostname(m)); if (!owl_message_is_pseudo(m)) { owl_fmtext_append_normal(&fm, "\n"); sprintf(buff, " Port : %i\n", ntohs(n->z_port)); owl_fmtext_append_normal(&fm, buff); owl_fmtext_append_normal(&fm, " Auth : "); owl_fmtext_append_normal(&fm, owl_zephyr_get_authstr(n)); owl_fmtext_append_normal(&fm, "\n"); /* fix this */ sprintf(buff, " Checkd Ath: %i\n", n->z_checked_auth); sprintf(buff, "%s Multi notc: %s\n", buff, n->z_multinotice); sprintf(buff, "%s Num other : %i\n", buff, n->z_num_other_fields); sprintf(buff, "%s Msg Len : %i\n", buff, n->z_message_len); owl_fmtext_append_normal(&fm, buff); sprintf(buff, " Fields : %i\n", owl_zephyr_get_num_fields(n)); owl_fmtext_append_normal(&fm, buff); fields=owl_zephyr_get_num_fields(n); for (i=0; iz_default_format); } } #endif } if (owl_message_is_type_aim(m)) { owl_fmtext_append_bold(&fm, "\nAIM Specific Information:\n"); } owl_fmtext_append_bold(&fm, "\nOwl Message Attributes:\n"); owl_message_attributes_tofmtext(m, &attrfm); owl_fmtext_append_fmtext(&fm, &attrfm); owl_function_popless_fmtext(&fm); owl_fmtext_free(&fm); owl_fmtext_free(&attrfm); } /* print the current message in a popup window. * Use the 'default' style regardless of whatever * style the user may be using */ void owl_function_curmsg_to_popwin() { owl_popwin *pw; owl_view *v; owl_message *m; owl_style *s; owl_fmtext fm; v=owl_global_get_current_view(&g); s=owl_global_get_style_by_name(&g, "default"); pw=owl_global_get_popwin(&g); m=owl_view_get_element(v, owl_global_get_curmsg(&g)); if (!m || owl_view_get_size(v)==0) { owl_function_error("No current message"); return; } owl_fmtext_init_null(&fm); owl_style_get_formattext(s, &fm, m); owl_function_popless_fmtext(&fm); owl_fmtext_free(&fm); } void owl_function_page_curmsg(int step) { /* scroll down or up within the current message IF the message is truncated */ int offset, curmsg, lines; owl_view *v; owl_message *m; offset=owl_global_get_curmsg_vert_offset(&g); v=owl_global_get_current_view(&g); curmsg=owl_global_get_curmsg(&g); m=owl_view_get_element(v, curmsg); if (!m || owl_view_get_size(v)==0) return; lines=owl_message_get_numlines(m); if (offset==0) { /* Bail if the curmsg isn't the last one displayed */ if (curmsg != owl_mainwin_get_last_msg(owl_global_get_mainwin(&g))) { owl_function_makemsg("The entire message is already displayed"); return; } /* Bail if we're not truncated */ if (!owl_mainwin_is_curmsg_truncated(owl_global_get_mainwin(&g))) { owl_function_makemsg("The entire message is already displayed"); return; } } /* don't scroll past the last line */ if (step>0) { if (offset+step > lines-1) { owl_global_set_curmsg_vert_offset(&g, lines-1); } else { owl_global_set_curmsg_vert_offset(&g, offset+step); } } /* would we be before the beginning of the message? */ if (step<0) { if (offset+step<0) { owl_global_set_curmsg_vert_offset(&g, 0); } else { owl_global_set_curmsg_vert_offset(&g, offset+step); } } /* redisplay */ owl_mainwin_redisplay(owl_global_get_mainwin(&g)); owl_global_set_needrefresh(&g); } void owl_function_resize_typwin(int newsize) { owl_global_set_typwin_lines(&g, newsize); owl_function_resize(); } void owl_function_typwin_grow() { int i; i=owl_global_get_typwin_lines(&g); owl_function_resize_typwin(i+1); } void owl_function_typwin_shrink() { int i; i=owl_global_get_typwin_lines(&g); if (i>2) { owl_function_resize_typwin(i-1); } } void owl_function_mainwin_pagedown() { int i; i=owl_mainwin_get_last_msg(owl_global_get_mainwin(&g)); if (i<0) return; if (owl_mainwin_is_last_msg_truncated(owl_global_get_mainwin(&g)) && (owl_global_get_curmsg(&g) < i) && (i>0)) { i--; } owl_global_set_curmsg(&g, i); owl_function_nextmsg(); } void owl_function_mainwin_pageup() { owl_global_set_curmsg(&g, owl_global_get_topmsg(&g)); owl_function_prevmsg(); } void owl_function_getsubs() { char *buff; buff=owl_zephyr_getsubs(); if (buff) { owl_function_popless_text(buff); } else { owl_function_popless_text("Error getting subscriptions"); } owl_free(buff); } #define PABUFLEN 5000 void owl_function_printallvars() { char buff[PABUFLEN], *pos, *name; owl_list varnames; int i, numvarnames, rem; pos = buff; pos += sprintf(pos, "%-20s = %s\n", "VARIABLE", "VALUE"); pos += sprintf(pos, "%-20s %s\n", "--------", "-----"); owl_variable_dict_get_names(owl_global_get_vardict(&g), &varnames); rem = (buff+PABUFLEN)-pos-1; numvarnames = owl_list_get_size(&varnames); for (i=0; i' for details)\n"); owl_variable_dict_get_names(owl_global_get_vardict(&g), &varnames); numvarnames = owl_list_get_size(&varnames); for (i=0; i' defined as "not filter ". If the * filter 'not-' already exists, do not overwrite it. If * 'filtername' begins with 'not-' and a filter 'filtername' already * exists, then do nothing. If the filter 'filtername' does not * exist, create it and define it as 'not filter ' * * Returns the name of the negated filter, which the caller must free. */ char *owl_function_create_negative_filter(char *filtername) { char *newname; owl_filter *tmpfilt; char *argv[5]; owl_function_debugmsg("owl_function_create_negative_filter"); if (!strncmp(filtername, "not-", 4)) { newname=owl_strdup(filtername+4); } else { newname=owl_sprintf("not-%s", filtername); } tmpfilt=owl_global_get_filter(&g, newname); if (!tmpfilt) { argv[0]="filter"; /* anything is fine here */ argv[1]=newname; argv[2]="not"; argv[3]="filter"; argv[4]=filtername; owl_function_create_filter(5, argv); } owl_function_debugmsg("owl_function_create_negative_filter: returning with %s", newname); return(newname); } void owl_function_show_filters() { owl_list *l; owl_filter *f; int i, j; owl_fmtext fm; owl_fmtext_init_null(&fm); l=owl_global_get_filterlist(&g); j=owl_list_get_size(l); owl_fmtext_append_bold(&fm, "Filters:\n"); for (i=0; i'. If a filter already * exists with this name, no new filter will be created. This allows * the configuration to override this function. Returns the name of * the filter, which the caller must free. */ char *owl_function_zuserfilt(char *user) { owl_filter *f; char *argbuff, *longuser, *shortuser, *filtname; /* stick the local realm on if it's not there */ longuser=long_zuser(user); shortuser=short_zuser(user); /* name for the filter */ filtname=owl_malloc(strlen(shortuser)+20); sprintf(filtname, "user-%s", shortuser); /* if it already exists then go with it. This lets users override */ if (owl_global_get_filter(&g, filtname)) { return(owl_strdup(filtname)); } /* create the new-internal filter */ f=owl_malloc(sizeof(owl_filter)); argbuff=owl_malloc(strlen(longuser)+1000); sprintf(argbuff, "( type ^zephyr$ and ( class ^message$ and instance ^personal$ and "); sprintf(argbuff, "%s ( ( direction ^in$ and sender ^%s$ ) or ( direction ^out$ and recipient ^%s$ ) ) )", argbuff, longuser, longuser); sprintf(argbuff, "%s or ( ( class ^login$ ) and ( sender ^%s$ ) ) )", argbuff, longuser); owl_filter_init_fromstring(f, filtname, argbuff); /* add it to the global list */ owl_global_add_filter(&g, f); /* free stuff */ owl_free(argbuff); owl_free(longuser); owl_free(shortuser); return(filtname); } /* Create a filter for AIM IM messages to or from the specified * screenname. The name of the filter will be 'aimuser-'. If a * filter already exists with this name, no new filter will be * created. This allows the configuration to override this function. * Returns the name of the filter, which the caller must free. */ char *owl_function_aimuserfilt(char *user) { owl_filter *f; char *argbuff, *filtname; /* name for the filter */ filtname=owl_malloc(strlen(user)+40); sprintf(filtname, "aimuser-%s", user); /* if it already exists then go with it. This lets users override */ if (owl_global_get_filter(&g, filtname)) { return(owl_strdup(filtname)); } /* create the new-internal filter */ f=owl_malloc(sizeof(owl_filter)); argbuff=owl_malloc(1000); sprintf(argbuff, "( type ^aim$ and ( ( sender ^%s$ and recipient ^%s$ ) or ( sender ^%s$ and recipient ^%s$ ) ) )", user, owl_global_get_aim_screenname(&g), owl_global_get_aim_screenname(&g), user); owl_filter_init_fromstring(f, filtname, argbuff); /* add it to the global list */ owl_global_add_filter(&g, f); /* free stuff */ owl_free(argbuff); return(filtname); } char *owl_function_typefilt(char *type) { owl_filter *f; char *argbuff, *filtname; /* name for the filter */ filtname=owl_sprintf("type-%s", type); /* if it already exists then go with it. This lets users override */ if (owl_global_get_filter(&g, filtname)) { return filtname; } /* create the new-internal filter */ f=owl_malloc(sizeof(owl_filter)); argbuff = owl_sprintf("type ^%s$", type); owl_filter_init_fromstring(f, filtname, argbuff); /* add it to the global list */ owl_global_add_filter(&g, f); /* free stuff */ owl_free(argbuff); return filtname; } /* If flag is 1, marks for deletion. If flag is 0, * unmarks for deletion. */ void owl_function_delete_curview_msgs(int flag) { owl_view *v; int i, j; v=owl_global_get_current_view(&g); j=owl_view_get_size(v); for (i=0; i", mclass, minst); } else { cmdprefix = "start-command zpunt "; cmd = owl_malloc(strlen(cmdprefix)+strlen(mclass)+strlen(minst)+10); strcpy(cmd, cmdprefix); strcat(cmd, owl_getquoting(mclass)); strcat(cmd, mclass); strcat(cmd, owl_getquoting(mclass)); if (type) { strcat(cmd, " "); strcat(cmd, owl_getquoting(minst)); strcat(cmd, minst); strcat(cmd, owl_getquoting(minst)); } else { strcat(cmd, " *"); } owl_function_command(cmd); owl_free(cmd); } } /* Set the color of the current view's filter to * be 'color' */ void owl_function_color_current_filter(char *fgcolor, char *bgcolor) { char *name; name=owl_view_get_filtname(owl_global_get_current_view(&g)); owl_function_color_filter(name, fgcolor, bgcolor); } /* Set the color of the filter 'filter' to be 'color'. If the color * name does not exist, return -1, if the filter does not exist or is * the "all" filter, return -2. Return 0 on success */ int owl_function_color_filter(char *filtname, char *fgcolor, char *bgcolor) { owl_filter *f; f=owl_global_get_filter(&g, filtname); if (!f) { owl_function_error("Unknown filter"); return(-2); } /* don't touch the all filter */ if (!strcmp(filtname, "all")) { owl_function_error("You may not change the 'all' filter."); return(-2); } if (owl_util_string_to_color(fgcolor)==-1) { owl_function_error("No color named '%s' avilable.", fgcolor); return(-1); } if (bgcolor != NULL) { if (owl_util_string_to_color(bgcolor)==-1) { owl_function_error("No color named '%s' avilable.", bgcolor); return(-1); } owl_filter_set_bgcolor(f, owl_util_string_to_color(bgcolor)); } owl_filter_set_fgcolor(f, owl_util_string_to_color(fgcolor)); owl_global_set_needrefresh(&g); owl_mainwin_redisplay(owl_global_get_mainwin(&g)); return(0); } void owl_function_show_colors() { owl_fmtext fm; owl_fmtext_init_null(&fm); owl_fmtext_append_normal(&fm, "default: "); owl_fmtext_append_normal_color(&fm, "default\n", OWL_COLOR_DEFAULT, OWL_COLOR_DEFAULT); owl_fmtext_append_normal(&fm,"red: "); owl_fmtext_append_normal_color(&fm, "red\n", OWL_COLOR_RED, OWL_COLOR_DEFAULT); owl_fmtext_append_normal(&fm,"green: "); owl_fmtext_append_normal_color(&fm, "green\n", OWL_COLOR_GREEN, OWL_COLOR_DEFAULT); owl_fmtext_append_normal(&fm,"yellow: "); owl_fmtext_append_normal_color(&fm, "yellow\n", OWL_COLOR_YELLOW, OWL_COLOR_DEFAULT); owl_fmtext_append_normal(&fm,"blue: "); owl_fmtext_append_normal_color(&fm, "blue\n", OWL_COLOR_BLUE, OWL_COLOR_DEFAULT); owl_fmtext_append_normal(&fm,"magenta: "); owl_fmtext_append_normal_color(&fm, "magenta\n", OWL_COLOR_MAGENTA, OWL_COLOR_DEFAULT); owl_fmtext_append_normal(&fm,"cyan: "); owl_fmtext_append_normal_color(&fm, "cyan\n", OWL_COLOR_CYAN, OWL_COLOR_DEFAULT); owl_fmtext_append_normal(&fm,"white: "); owl_fmtext_append_normal_color(&fm, "white\n", OWL_COLOR_WHITE, OWL_COLOR_DEFAULT); owl_function_popless_fmtext(&fm); owl_fmtext_free(&fm); } /* add the given class, inst, recip to the punt list for filtering. * if direction==0 then punt * if direction==1 then unpunt */ void owl_function_zpunt(char *class, char *inst, char *recip, int direction) { owl_filter *f; owl_list *fl; char *buff; char *quoted; int ret, i, j; fl=owl_global_get_puntlist(&g); /* first, create the filter */ f=malloc(sizeof(owl_filter)); buff=malloc(strlen(class)+strlen(inst)+strlen(recip)+100); strcpy(buff, "class"); if (!strcmp(class, "*")) { strcat(buff, " .*"); } else { quoted=owl_text_quote(class, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH); owl_text_tr(quoted, ' ', '.'); sprintf(buff, "%s ^(un)*%s(\\.d)*$", buff, quoted); owl_free(quoted); } if (!strcmp(inst, "*")) { strcat(buff, " and instance .*"); } else { quoted=owl_text_quote(inst, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH); owl_text_tr(quoted, ' ', '.'); sprintf(buff, "%s and instance ^(un)*%s(\\.d)*$", buff, quoted); owl_free(quoted); } if (strcmp(recip, "*")) { quoted=owl_text_quote(recip, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH); owl_text_tr(quoted, ' ', '.'); sprintf(buff, "%s and recipient ^%s$", buff, quoted); owl_free(quoted); } owl_function_debugmsg("About to filter %s", buff); ret=owl_filter_init_fromstring(f, "punt-filter", buff); owl_free(buff); if (ret) { owl_function_error("Error creating filter for zpunt"); owl_filter_free(f); return; } /* Check for an identical filter */ j=owl_list_get_size(fl); for (i=0; i' for details)\n"); owl_keyhandler_get_keymap_names(kh, &l); owl_fmtext_append_list(&fm, &l, "\n", owl_function_keymap_summary); owl_fmtext_append_normal(&fm, "\n"); numkm = owl_list_get_size(&l); for (i=0; i=viewsize || start<0) { owl_function_error("No further matches found"); return; } for (i=start; i=0;) { m=owl_view_get_element(v, i); if (owl_message_search(m, owl_global_get_search_string(&g))) { owl_global_set_curmsg(&g, i); owl_function_calculate_topmsg(direction); owl_mainwin_redisplay(owl_global_get_mainwin(&g)); if (direction==OWL_DIRECTION_DOWNWARDS) { owl_global_set_direction_downwards(&g); } else { owl_global_set_direction_upwards(&g); } return; } if (direction==OWL_DIRECTION_DOWNWARDS) { i++; } else { i--; } } owl_mainwin_redisplay(owl_global_get_mainwin(&g)); owl_function_error("No matches found"); } /* strips formatting from ztext and returns the unformatted text. * caller is responsible for freeing. */ char *owl_function_ztext_stylestrip(char *zt) { owl_fmtext fm; char *plaintext; owl_fmtext_init_null(&fm); owl_fmtext_append_ztext(&fm, zt); plaintext = owl_fmtext_print_plain(&fm); owl_fmtext_free(&fm); return(plaintext); } /* Popup a buddylisting. If filename is NULL use the default .anyone */ void owl_function_buddylist(int aim, int zephyr, char *filename) { int i, j, x, idle; owl_fmtext fm; owl_buddylist *bl; owl_buddy *b; owl_list anyone; char *foo, *timestr; #ifdef HAVE_LIBZEPHYR char *tmp, *user, *line; ZLocations_t location[200]; int numlocs, ret; #endif owl_fmtext_init_null(&fm); /* AIM first */ if (aim && owl_global_is_aimloggedin(&g)) { bl=owl_global_get_buddylist(&g); owl_fmtext_append_bold(&fm, "AIM users logged in:\n"); /* we're assuming AIM for now */ j=owl_buddylist_get_size(bl); for (i=0; i=200) { owl_fmtext_append_normal(&fm, " Too many locations found for this user, truncating.\n"); } } } } owl_list_free_all(&anyone, owl_free); } } #endif if(aim && zephyr) { if(owl_perlconfig_is_function("BarnOwl::Hooks::get_blist")) { char * perlblist = owl_perlconfig_execute("BarnOwl::Hooks::get_blist()"); if(perlblist) { owl_fmtext_append_ztext(&fm, perlblist); owl_free(perlblist); } } } owl_function_popless_fmtext(&fm); owl_fmtext_free(&fm); } /* Dump messages in the current view to the file 'filename'. */ void owl_function_dump(char *filename) { int i, j, count; owl_message *m; owl_view *v; FILE *file; v=owl_global_get_current_view(&g); /* in the future make it ask yes/no */ /* ret=stat(filename, &sbuf); if (!ret) { ret=owl_function_askyesno("File exists, continue? [Y/n]"); if (!ret) return; } */ file=fopen(filename, "w"); if (!file) { owl_function_error("Error opening file"); return; } count=0; j=owl_view_get_size(v); for (i=0; i0) && !owl_zbuddylist_contains_user(zbl, user)) { /* Send a PSEUDO LOGIN! */ if (notify) { m=owl_malloc(sizeof(owl_message)); owl_message_create_pseudo_zlogin(m, 0, user, location[0].host, location[0].time, location[0].tty); owl_global_messagequeue_addmsg(&g, m); } owl_zbuddylist_adduser(zbl, user); owl_function_debugmsg("owl_function_zephyr_buddy_check: login for %s ", user); } else if ((numlocs==0) && owl_zbuddylist_contains_user(zbl, user)) { /* I don't think this ever happens (if there are 0 locations we should get an error from * ZGetLocations) */ owl_function_error("owl_function_zephyr_buddy_check: exceptional case logout for %s ",user); } } else if ((ret==ZERR_NOLOCATIONS) && owl_zbuddylist_contains_user(zbl, user)) { /* Send a PSEUDO LOGOUT! */ if (notify) { m=owl_malloc(sizeof(owl_message)); owl_message_create_pseudo_zlogin(m, 1, user, "", "", ""); owl_global_messagequeue_addmsg(&g, m); } owl_zbuddylist_deluser(zbl, user); owl_function_debugmsg("owl_function_zephyr_buddy_check: logout for %s ",user); } } owl_list_free_all(&anyone, owl_free); #endif } void owl_function_aimsearch_results(char *email, owl_list *namelist) { owl_fmtext fm; int i, j; owl_fmtext_init_null(&fm); owl_fmtext_append_normal(&fm, "AIM screennames associated with "); owl_fmtext_append_normal(&fm, email); owl_fmtext_append_normal(&fm, ":\n"); j=owl_list_get_size(namelist); for (i=0; i