/* * Handles commands the user sends. * * Copyright: This file may be distributed under version 2 of the GPL licence. * * alias stuff GPL >= v2 * * $Id$ */ #include "micq.h" #include "cmd_user.h" #include "util.h" #include "util_ui.h" #include "util_io.h" #include "util_table.h" #include "util_extra.h" #include "cmd_pkt_cmd_v5.h" #include "cmd_pkt_cmd_v5_util.h" #include "cmd_pkt_v8.h" #include "cmd_pkt_v8_flap.h" #include "cmd_pkt_v8_snac.h" #include "preferences.h" #include "packet.h" #include "tabs.h" #include "session.h" #include "tcp.h" #include "icq_response.h" #include "conv.h" #include "file_util.h" #include "buildmark.h" #include "contact.h" #include "server.h" #include "util_str.h" #include "util_tcl.h" #include "util_ssl.h" #include #include #include #include static jump_f CmdUserChange, CmdUserRandom, CmdUserHelp, CmdUserInfo, CmdUserTrans, CmdUserAuto, CmdUserAlter, CmdUserAlias, CmdUserUnalias, CmdUserMessage, CmdUserMessageNG, CmdUserResend, CmdUserPeek, CmdUserAsSession, CmdUserVerbose, CmdUserRandomSet, CmdUserIgnoreStatus, CmdUserSMS, CmdUserStatusDetail, CmdUserStatusWide, CmdUserStatusShort, CmdUserSound, CmdUserSoundOnline, CmdUserRegister, CmdUserStatusMeta, CmdUserSoundOffline, CmdUserAutoaway, CmdUserSet, CmdUserClear, CmdUserTogIgnore, CmdUserTogInvis, CmdUserTogVisible, CmdUserAdd, CmdUserRemove, CmdUserAuth, CmdUserURL, CmdUserSave, CmdUserTabs, CmdUserLast, CmdUserUptime, CmdUserOldSearch, CmdUserSearch, CmdUserUpdate, CmdUserPass, CmdUserOther, CmdUserAbout, CmdUserQuit, CmdUserPeer, CmdUserConn, CmdUserContact, CmdUserAnyMess, CmdUserGetAuto; static void CmdUserProcess (const char *command, time_t *idle_val, UBYTE *idle_flag); /* 1 = do not apply idle stuff next time v 2 = count this line as being idle v */ static jump_t jump[] = { { &CmdUserRandom, "rand", NULL, 0, 0 }, { &CmdUserRandomSet, "setr", NULL, 0, 0 }, { &CmdUserHelp, "help", NULL, 0, 0 }, { &CmdUserInfo, "f", NULL, 0, 0 }, { &CmdUserInfo, "finger", NULL, 0, 0 }, { &CmdUserInfo, "info", NULL, 0, 0 }, { &CmdUserInfo, "rinfo", NULL, 0, 1 }, { &CmdUserTrans, "lang", NULL, 0, 0 }, { &CmdUserTrans, "trans", NULL, 0, 0 }, { &CmdUserAuto, "auto", NULL, 0, 0 }, { &CmdUserAlter, "alter", NULL, 0, 0 }, { &CmdUserAlias, "alias", NULL, 0, 0 }, { &CmdUserUnalias, "unalias", NULL, 0, 0 }, { &CmdUserAnyMess, "message", NULL, 0, 0 }, { &CmdUserMessageNG, "msg", NULL, 0, 1 }, { &CmdUserMessageNG, "r", NULL, 0, 2 }, { &CmdUserMessageNG, "a", NULL, 0, 4 }, { &CmdUserGetAuto, "getauto", NULL, 0, 0 }, { &CmdUserMessage, "msg-old", NULL, 0, 1 }, { &CmdUserResend, "resend", NULL, 0, 0 }, { &CmdUserVerbose, "verbose", NULL, 0, 0 }, { &CmdUserIgnoreStatus, "i", NULL, 0, 0 }, { &CmdUserStatusDetail, "status", NULL, 2, 10 }, { &CmdUserStatusDetail, "ww", NULL, 2, 2 }, { &CmdUserStatusDetail, "ee", NULL, 2, 3 }, { &CmdUserStatusDetail, "w", NULL, 2, 4 }, { &CmdUserStatusDetail, "e", NULL, 2, 5 }, { &CmdUserStatusDetail, "wwg", NULL, 2, 34 }, { &CmdUserStatusDetail, "eeg", NULL, 2, 35 }, { &CmdUserStatusDetail, "wg", NULL, 2, 36 }, { &CmdUserStatusDetail, "eg", NULL, 2, 37 }, { &CmdUserStatusDetail, "s", NULL, 2, 30 }, { &CmdUserStatusDetail, "s-any", NULL, 2, 0 }, { &CmdUserStatusMeta, "ss", NULL, 2, 1 }, { &CmdUserStatusMeta, "meta", NULL, 2, 0 }, { &CmdUserStatusShort, "w-old", NULL, 2, 1 }, { &CmdUserStatusShort, "e-old", NULL, 2, 0 }, { &CmdUserStatusWide, "wide", NULL, 2, 1 }, { &CmdUserStatusWide, "ewide", NULL, 2, 0 }, { &CmdUserSet, "set", NULL, 0, 0 }, { &CmdUserSound, "sound", NULL, 2, 0 }, { &CmdUserSoundOnline, "soundonline", NULL, 2, 0 }, { &CmdUserSoundOffline, "soundoffline", NULL, 2, 0 }, { &CmdUserAutoaway, "autoaway", NULL, 2, 0 }, { &CmdUserChange, "change", NULL, 1, -1 }, { &CmdUserChange, "online", NULL, 1, STATUS_ONLINE }, { &CmdUserChange, "away", NULL, 1, STATUS_AWAY }, { &CmdUserChange, "na", NULL, 1, STATUS_NA }, { &CmdUserChange, "occ", NULL, 1, STATUS_OCC }, { &CmdUserChange, "dnd", NULL, 1, STATUS_DND }, { &CmdUserChange, "ffc", NULL, 1, STATUS_FFC }, { &CmdUserChange, "inv", NULL, 1, STATUS_INV }, { &CmdUserClear, "clear", NULL, 2, 0 }, { &CmdUserTogIgnore, "togig", NULL, 0, 0 }, { &CmdUserTogVisible, "togvis", NULL, 0, 0 }, { &CmdUserTogInvis, "toginv", NULL, 0, 0 }, { &CmdUserAdd, "add", NULL, 0, 0 }, { &CmdUserAdd, "addalias", NULL, 0, 1 }, { &CmdUserAdd, "addgroup", NULL, 0, 2 }, { &CmdUserRemove, "rem", NULL, 0, 0 }, { &CmdUserRemove, "remalias", NULL, 0, 1 }, { &CmdUserRemove, "remgroup", NULL, 0, 2 }, { &CmdUserRegister, "reg", NULL, 0, 0 }, { &CmdUserAuth, "auth", NULL, 0, 0 }, { &CmdUserURL, "url", NULL, 0, 0 }, { &CmdUserSave, "save", NULL, 0, 0 }, { &CmdUserTabs, "tabs", NULL, 0, 0 }, { &CmdUserLast, "last", NULL, 0, 0 }, { &CmdUserUptime, "uptime", NULL, 0, 0 }, { &CmdUserPeer, "peer", NULL, 0, 0 }, { &CmdUserPeer, "tcp", NULL, 0, 0 }, { &CmdUserPeer, "file", NULL, 0, 4 }, { &CmdUserPeer, "accept", NULL, 0, 22 }, { &CmdUserQuit, "q", NULL, 0, 0 }, { &CmdUserQuit, "quit", NULL, 0, 0 }, { &CmdUserQuit, "exit", NULL, 0, 0 }, { &CmdUserPass, "pass", NULL, 0, 0 }, { &CmdUserSMS, "sms", NULL, 0, 0 }, { &CmdUserPeek, "peek", NULL, 0, 0 }, { &CmdUserAsSession, "as", NULL, 0, 0 }, { &CmdUserContact, "contact", NULL, 0, 0 }, { &CmdUserContact, "contactshow", NULL, 0, 1 }, { &CmdUserContact, "contactdiff", NULL, 0, 2 }, { &CmdUserContact, "contactadd", NULL, 0, 3 }, { &CmdUserContact, "contactdl", NULL, 0, 1 }, { &CmdUserOldSearch, "oldsearch", NULL, 0, 0 }, { &CmdUserSearch, "search", NULL, 0, 0 }, { &CmdUserUpdate, "update", NULL, 0, 0 }, { &CmdUserOther, "other", NULL, 0, 0 }, { &CmdUserAbout, "about", NULL, 0, 0 }, { &CmdUserConn, "conn", NULL, 0, 0 }, { &CmdUserConn, "login", NULL, 0, 2 }, #ifdef ENABLE_TCL { &CmdUserTclScript, "tclscript", NULL, 0, 0 }, { &CmdUserTclScript, "tcl", NULL, 0, 1 }, #endif /* ENABLE_TCL */ { NULL, NULL, NULL, 0 } }; static alias_t *aliases = NULL; static Connection *currconn = NULL; /* Have an opened server connection ready. */ #define OPENCONN Connection *conn = currconn; \ if (!conn) currconn = conn = ConnectionFind (TYPEF_ANY_SERVER, 0, NULL); \ if (!conn || ~conn->connect & CONNECT_OK) \ { M_print (i18n (1931, "Current session is closed. Try another or open this one.\n")); return 0; } /* Try to have any server connection ready. */ #define ANYCONN Connection *conn = currconn; \ if (!conn) currconn = conn = ConnectionFind (TYPEF_ANY_SERVER, 0, NULL); /* * Returns a pointer to the jump table. */ jump_t *CmdUserTable (void) { return jump; } /* * Looks up an entry in the jump table. */ jump_t *CmdUserLookup (const char *cmd, int flags) { jump_t *j; for (j = CmdUserTable (); j->f; j++) if ( ((flags & CU_DEFAULT) && j->defname && !strcasecmp (cmd, j->defname)) || ((flags & CU_USER) && j->name && !strcasecmp (cmd, j->name))) return j; return NULL; } /* * Looks up just the current command name. */ const char *CmdUserLookupName (const char *cmd) { jump_t *j; j = CmdUserLookup (cmd, CU_DEFAULT); if (!j) j = CmdUserLookup (cmd, CU_USER); if (!j) return ""; if (j->name) return j->name; return j->defname; } /* * Returns the alias list. */ alias_t *CmdUserAliases (void) { return aliases; } /* * Looks up an alias. */ alias_t *CmdUserLookupAlias (const char *name) { alias_t *node; for (node = aliases; node; node = node->next) if (!strcasecmp (name, node->name)) break; return node; } /* * Sets an alias. */ alias_t *CmdUserSetAlias (const char *name, const char *expansion) { alias_t *alias; alias = CmdUserLookupAlias (name); if (!alias) { alias = calloc (1, sizeof (alias_t)); if (aliases) { alias_t *node; for (node = aliases; node->next; node = node->next) ; node->next = alias; } else aliases = alias; } s_repl (&alias->name, name); s_repl (&alias->expansion, expansion); return alias; } /* * Removes an alias. */ int CmdUserRemoveAlias (const char *name) { alias_t *node, *prev_node = NULL; for (node = aliases; node; node = node->next) { if (!strcasecmp (name, node->name)) break; prev_node = node; } if (node) { if (prev_node) prev_node->next = node->next; else aliases = node->next; free (node->name); free (node->expansion); free (node); return TRUE; } else return FALSE; } /* * Change status. */ static JUMP_F(CmdUserChange) { char *arg1 = NULL; OPENCONN; if (data == -1) { if (!s_parseint (&args, &data)) { M_print (i18n (1703, "Status modes:\n")); M_printf (" %-20s %d\n", i18n (1921, "Online"), STATUS_ONLINE); M_printf (" %-20s %d\n", i18n (1923, "Away"), STATUS_AWAY); M_printf (" %-20s %d\n", i18n (1922, "Do not disturb"), STATUS_DND); M_printf (" %-20s %d\n", i18n (1924, "Not Available"), STATUS_NA); M_printf (" %-20s %d\n", i18n (1927, "Free for chat"), STATUS_FFC); M_printf (" %-20s %d\n", i18n (1925, "Occupied"), STATUS_OCC); M_printf (" %-20s %d\n", i18n (1926, "Invisible"), STATUS_INV); return 0; } } if (s_parserem (&args, &arg1)) { if (data & STATUSF_DND) s_repl (&prG->auto_dnd, arg1); else if (data & STATUSF_OCC) s_repl (&prG->auto_occ, arg1); else if (data & STATUSF_NA) s_repl (&prG->auto_na, arg1); else if (data & STATUSF_AWAY) s_repl (&prG->auto_away, arg1); else if (data & STATUSF_FFC) s_repl (&prG->auto_ffc, arg1); } if (conn->ver > 6) SnacCliSetstatus (conn, data, 1); else { CmdPktCmdStatusChange (conn, data); M_printf ("%s %s\n", s_now, s_status (conn->status)); } return 0; } /* * Finds random user. */ static JUMP_F(CmdUserRandom) { UDWORD arg1 = 0; OPENCONN; if (!s_parseint (&args, &arg1)) { M_print (i18n (1704, "Groups:\n")); M_printf (" %2d %s\n", 1, i18n (1705, "General")); M_printf (" %2d %s\n", 2, i18n (1706, "Romance")); M_printf (" %2d %s\n", 3, i18n (1707, "Games")); M_printf (" %2d %s\n", 4, i18n (1708, "Students")); M_printf (" %2d %s\n", 6, i18n (1709, "20 something")); M_printf (" %2d %s\n", 7, i18n (1710, "30 something")); M_printf (" %2d %s\n", 8, i18n (1711, "40 something")); M_printf (" %2d %s\n", 9, i18n (1712, "50+")); M_printf (" %2d %s\n", 10, i18n (1713, "Seeking women")); M_printf (" %2d %s\n", 11, i18n (1714, "Seeking men")); M_printf (" %2d %s\n", 49, i18n (1715, "mICQ")); } else IMCliInfo (conn, NULL, arg1); return 0; } /* * Sets the random user group. */ static JUMP_F(CmdUserRandomSet) { UDWORD arg1 = 0; OPENCONN; if (!s_parseint (&args, &arg1)) { M_print (i18n (1704, "Groups:\n")); M_printf (" %2d %s\n", conn->ver > 6 ? 0 : -1, i18n (1716, "None")); M_printf (" %2d %s\n", 1, i18n (1705, "General")); M_printf (" %2d %s\n", 2, i18n (1706, "Romance")); M_printf (" %2d %s\n", 3, i18n (1707, "Games")); M_printf (" %2d %s\n", 4, i18n (1708, "Students")); M_printf (" %2d %s\n", 6, i18n (1709, "20 something")); M_printf (" %2d %s\n", 7, i18n (1710, "30 something")); M_printf (" %2d %s\n", 8, i18n (1711, "40 something")); M_printf (" %2d %s\n", 9, i18n (1712, "50+")); M_printf (" %2d %s\n", 10, i18n (1713, "Seeking women")); M_printf (" %2d %s\n", 11, i18n (1714, "Seeking men")); M_printf (" %2d %s\n", 49, i18n (1715, "mICQ")); } else { if (conn->ver > 6) SnacCliSetrandom (conn, arg1); else CmdPktCmdRandSet (conn, arg1); } return 0; } /* * Displays help. */ static JUMP_F(CmdUserHelp) { char *arg1 = NULL; char what; s_parse (&args, &arg1); if (!arg1) what = 0; else if (!strcasecmp (arg1, i18n (1447, "Client")) || !strcasecmp (arg1, "Client")) what = 1; else if (!strcasecmp (arg1, i18n (1448, "Message")) || !strcasecmp (arg1, "Message")) what = 2; else if (!strcasecmp (arg1, i18n (1449, "User")) || !strcasecmp (arg1, "User")) what = 3; else if (!strcasecmp (arg1, i18n (1450, "Account")) || !strcasecmp (arg1, "Account")) what = 4; else if (!strcasecmp (arg1, i18n (2171, "Advanced")) || !strcasecmp (arg1, "Advanced")) what = 5; #ifdef ENABLE_TCL else if (!strcasecmp (arg1, i18n (2342, "Scripting")) || !strcasecmp (arg1, "Scripting")) what = 6; #endif /* ENABLE_TCL */ else what = 0; if (!what) { const char *fmt = i18n (2184, "%s%-10s%s - %s\n"); M_printf ("%s\n", i18n (1442, "Please select one of the help topics below.")); M_printf (fmt, COLCLIENT, i18n (1448, "Message"), COLNONE, i18n (1446, "Commands relating to sending messages.")); M_printf (fmt, COLCLIENT, i18n (1447, "Client"), COLNONE, i18n (1443, "Commands relating to mICQ displays and configuration.")); M_printf (fmt, COLCLIENT, i18n (1449, "User"), COLNONE, i18n (1444, "Commands relating to finding and seeing other users.")); M_printf (fmt, COLCLIENT, i18n (1450, "Account"), COLNONE, i18n (1445, "Commands relating to your ICQ account.")); M_printf (fmt, COLCLIENT, i18n (2171, "Advanced"), COLNONE, i18n (2172, "Commands for advanced features.")); #ifdef ENABLE_TCL M_printf (fmt, COLCLIENT, "Scripting", COLNONE, i18n (2343, "Scripting extensions.")); #endif /* ENABLE_TCL */ } else if (what == 1) { M_printf (COLMESSAGE "%s []" COLNONE "\n\t" COLINDENT "%s" COLEXDENT "\n", CmdUserLookupName ("verbose"), i18n (1418, "Set the verbosity level, or display verbosity level.")); M_printf (COLMESSAGE "%s" COLNONE "\n\t" COLINDENT "%s" COLEXDENT "\n", CmdUserLookupName ("clear"), i18n (1419, "Clears the screen.")); M_printf (COLMESSAGE "%s [%s|%s|event]" COLNONE "\n\t" COLINDENT "%s" COLEXDENT "\n", CmdUserLookupName ("sound"), i18n (1085, "on"), i18n (1086, "off"), i18n (1420, "Switches beeping when receiving new messages on or off, or using the event script.")); M_printf (COLMESSAGE "%s []" COLNONE "\n\t" COLINDENT "%s" COLEXDENT "\n", CmdUserLookupName ("autoaway"), i18n (1767, "Toggles auto cycling to away/not available.")); M_printf (COLMESSAGE "%s [on|off]" COLNONE "\n\t" COLINDENT "%s" COLEXDENT "\n", CmdUserLookupName ("auto"), i18n (1424, "Set whether autoreplying when not online, or displays setting.")); M_printf (COLMESSAGE "%s " COLNONE "\n\t" COLINDENT "%s" COLEXDENT "\n", CmdUserLookupName ("auto"), i18n (1425, "Sets the message to send as an auto reply for the status.")); M_printf (COLMESSAGE "%s [ ]" COLNONE "\n\t" COLINDENT "%s" COLEXDENT "\n", CmdUserLookupName ("alias"), i18n (2300, "Set an alias or list current aliases.")); M_printf (COLMESSAGE "%s " COLNONE "\n\t" COLINDENT "%s" COLEXDENT "\n", CmdUserLookupName ("unalias"), i18n (2301, "Delete an alias.")); M_printf (COLMESSAGE "%s [...]" COLNONE "\n\t" COLINDENT "%s" COLEXDENT "\n", CmdUserLookupName ("trans"), i18n (1800, "Change the working language to or display string .")); M_printf (COLMESSAGE "%s" COLNONE "\n\t" COLINDENT "%s" COLEXDENT "\n", CmdUserLookupName ("uptime"), i18n (1719, "Shows how long mICQ has been running and some statistics.")); M_printf (COLMESSAGE "%s