4 Copyright (C) 1999-2001 Timo Sirainen
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "module-formats.h"
29 #include "printtext.h"
31 #include "gui-windows.h"
32 #include "gui-printtext.h"
34 #define MAX_LINES_WITHOUT_FORCE 1000
36 static void window_lastlog_clear(WINDOW_REC *window)
38 TEXT_BUFFER_VIEW_REC *view;
41 screen_refresh_freeze();
42 view = WINDOW_GUI(window)->view;
43 for (tmp = textbuffer_view_get_lines(view); tmp != NULL; tmp = next) {
44 LINE_REC *line = tmp->data;
47 if (line->info.level & MSGLEVEL_LASTLOG)
48 textbuffer_view_remove_line(view, line);
50 textbuffer_view_redraw(view);
51 screen_refresh_thaw();
54 /* Only unknown keys in `optlist' should be levels.
55 Returns -1 if unknown option was given. */
56 int cmd_options_get_level(const char *cmd, GHashTable *optlist)
58 GSList *list, *tmp, *next;
61 /* get all the options, then remove the known ones. there should
62 be only one left - the server tag. */
63 list = hashtable_get_keys(optlist);
65 for (tmp = list; tmp != NULL; tmp = next) {
66 char *option = tmp->data;
69 if (command_have_option(cmd, option))
70 list = g_slist_remove(list, option);
75 while (list != NULL) {
76 level = level_get(list->data);
79 signal_emit("error command", 2,
80 GINT_TO_POINTER(CMDERR_OPTION_UNKNOWN),
87 list = g_slist_remove(list, list->data);
93 static void show_lastlog(const char *searchtext, GHashTable *optlist,
94 int start, int count, int fhandle)
103 level = cmd_options_get_level("lastlog", optlist);
104 if (level == -1) return; /* error in options */
105 if (level == 0) level = MSGLEVEL_ALL;
107 if (g_hash_table_lookup(optlist, "clear") != NULL) {
108 window_lastlog_clear(active_win);
109 if (*searchtext == '\0')
113 /* which window's lastlog to look at? */
115 str = g_hash_table_lookup(optlist, "window");
117 window = is_numeric(str, '\0') ?
118 window_find_refnum(atoi(str)) :
119 window_find_item(NULL, str);
120 if (window == NULL) {
121 printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
122 TXT_REFNUM_NOT_FOUND, str);
127 if (g_hash_table_lookup(optlist, "new") != NULL)
128 startline = textbuffer_view_get_bookmark(WINDOW_GUI(window)->view, "lastlog_last_check");
129 else if (g_hash_table_lookup(optlist, "away") != NULL)
130 startline = textbuffer_view_get_bookmark(WINDOW_GUI(window)->view, "lastlog_last_away");
134 if (startline == NULL) {
135 list = textbuffer_view_get_lines(WINDOW_GUI(window)->view);
136 startline = list == NULL ? NULL : list->data;
139 list = textbuffer_find_text(WINDOW_GUI(window)->view->buffer, startline,
140 level, MSGLEVEL_LASTLOG,
142 g_hash_table_lookup(optlist, "regexp") != NULL,
143 g_hash_table_lookup(optlist, "word") != NULL,
144 g_hash_table_lookup(optlist, "case") != NULL);
146 len = g_list_length(list);
152 if (pos < 0) pos = 0;
155 tmp = pos > len ? NULL : g_list_nth(list, pos);
156 len = g_list_length(tmp);
159 if (len > MAX_LINES_WITHOUT_FORCE && fhandle == -1 &&
160 g_hash_table_lookup(optlist, "force") == NULL) {
161 printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
162 TXT_LASTLOG_TOO_LONG, len);
167 if (fhandle == -1 && g_hash_table_lookup(optlist, "-") == NULL)
168 printformat(NULL, NULL, MSGLEVEL_LASTLOG, TXT_LASTLOG_START);
170 line = g_string_new(NULL);
171 while (tmp != NULL && (count < 0 || count > 0)) {
172 LINE_REC *rec = tmp->data;
174 /* get the line text */
175 textbuffer_line2text(rec, fhandle == -1, line);
176 if (!settings_get_bool("timestamps")) {
177 struct tm *tm = localtime(&rec->info.time);
180 g_snprintf(timestamp, sizeof(timestamp),
182 tm->tm_hour, tm->tm_min);
183 g_string_prepend(line, timestamp);
186 /* write to file/window */
188 write(fhandle, line->str, line->len);
189 write(fhandle, "\n", 1);
191 printtext_window(active_win, MSGLEVEL_LASTLOG,
198 g_string_free(line, TRUE);
200 if (fhandle == -1 && g_hash_table_lookup(optlist, "-") == NULL)
201 printformat(NULL, NULL, MSGLEVEL_LASTLOG, TXT_LASTLOG_END);
203 textbuffer_view_set_bookmark_bottom(WINDOW_GUI(window)->view,
204 "lastlog_last_check");
206 textbuffer_line_unref_list(WINDOW_GUI(window)->view->buffer, list);
210 /* SYNTAX: LASTLOG [-] [-file <filename>] [-clear] [-<level> -<level...>]
211 [-new | -away] [-regexp | -word] [-case]
212 [-window <ref#|name>] [<pattern>] [<count> [<start>]] */
213 static void cmd_lastlog(const char *data)
216 char *text, *countstr, *start, *fname;
220 g_return_if_fail(data != NULL);
222 if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS,
223 "lastlog", &optlist, &text, &countstr, &start))
226 if (*start == '\0' && is_numeric(text, 0)) {
227 if (is_numeric(countstr, 0))
232 count = atoi(countstr);
233 if (count == 0) count = -1;
235 /* target where to print it */
237 fname = g_hash_table_lookup(optlist, "file");
239 fname = convert_home(fname);
240 fhandle = open(fname, O_WRONLY | O_APPEND | O_CREAT,
241 octal2dec(settings_get_int("log_create_mode")));
245 if (fname != NULL && fhandle == -1) {
246 printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
247 "%s", g_strerror(errno));
249 show_lastlog(text, optlist, atoi(start), count, fhandle);
254 cmd_params_free(free_arg);
257 void lastlog_init(void)
259 command_bind("lastlog", NULL, (SIGNAL_FUNC) cmd_lastlog);
261 command_set_options("lastlog", "!- force clear -file -window new away word regexp case");
264 void lastlog_deinit(void)
266 command_unbind("lastlog", (SIGNAL_FUNC) cmd_lastlog);