~ubuntu-branches/ubuntu/intrepid/irssi/intrepid-updates

« back to all changes in this revision

Viewing changes to src/fe-text/lastlog.c

  • Committer: Bazaar Package Importer
  • Author(s): David Pashley
  • Date: 2005-12-10 21:25:51 UTC
  • Revision ID: james.westby@ubuntu.com-20051210212551-5qwm108g7inyu2f2
Tags: upstream-0.8.10
ImportĀ upstreamĀ versionĀ 0.8.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 lastlog.c : irssi
 
3
 
 
4
    Copyright (C) 1999-2001 Timo Sirainen
 
5
 
 
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.
 
10
 
 
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.
 
15
 
 
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
 
19
*/
 
20
 
 
21
#include "module.h"
 
22
#include "signals.h"
 
23
#include "commands.h"
 
24
#include "misc.h"
 
25
#include "levels.h"
 
26
#include "settings.h"
 
27
 
 
28
#include "module-formats.h"
 
29
#include "printtext.h"
 
30
 
 
31
#include "gui-windows.h"
 
32
#include "gui-printtext.h"
 
33
 
 
34
#define DEFAULT_LASTLOG_BEFORE 3
 
35
#define DEFAULT_LASTLOG_AFTER 3
 
36
#define MAX_LINES_WITHOUT_FORCE 1000
 
37
 
 
38
static void window_lastlog_clear(WINDOW_REC *window)
 
39
{
 
40
        TEXT_BUFFER_VIEW_REC *view;
 
41
        LINE_REC *line, *next;
 
42
 
 
43
        term_refresh_freeze();
 
44
        view = WINDOW_GUI(window)->view;
 
45
        line = textbuffer_view_get_lines(view);
 
46
 
 
47
        while (line != NULL) {
 
48
                next = line->next;
 
49
 
 
50
                if (line->info.level & MSGLEVEL_LASTLOG)
 
51
                        textbuffer_view_remove_line(view, line);
 
52
                line = next;
 
53
        }
 
54
        textbuffer_view_redraw(view);
 
55
        term_refresh_thaw();
 
56
}
 
57
 
 
58
/* Only unknown keys in `optlist' should be levels.
 
59
   Returns -1 if unknown option was given. */
 
60
int cmd_options_get_level(const char *cmd, GHashTable *optlist)
 
61
{
 
62
        GSList *list, *tmp, *next;
 
63
        int level, retlevel;
 
64
 
 
65
        /* get all the options, then remove the known ones. there should
 
66
           be only one left - the server tag. */
 
67
        list = hashtable_get_keys(optlist);
 
68
        if (cmd != NULL) {
 
69
                for (tmp = list; tmp != NULL; tmp = next) {
 
70
                        char *option = tmp->data;
 
71
                        next = tmp->next;
 
72
 
 
73
                        if (command_have_option(cmd, option))
 
74
                                list = g_slist_remove(list, option);
 
75
                }
 
76
        }
 
77
 
 
78
        retlevel = 0;
 
79
        while (list != NULL) {
 
80
                level = level_get(list->data);
 
81
                if (level == 0) {
 
82
                        /* unknown option */
 
83
                        signal_emit("error command", 2,
 
84
                                    GINT_TO_POINTER(CMDERR_OPTION_UNKNOWN),
 
85
                                    list->data);
 
86
                        retlevel = -1;
 
87
                        break;
 
88
                }
 
89
 
 
90
                retlevel |= level;
 
91
                list = g_slist_remove(list, list->data);
 
92
        }
 
93
 
 
94
        return retlevel;
 
95
}
 
96
 
 
97
static void show_lastlog(const char *searchtext, GHashTable *optlist,
 
98
                         int start, int count, int fhandle)
 
99
{
 
100
        WINDOW_REC *window;
 
101
        LINE_REC *startline;
 
102
        GList *list, *tmp;
 
103
        GString *line;
 
104
        char *str;
 
105
        int level, before, after, len;
 
106
 
 
107
        level = cmd_options_get_level("lastlog", optlist);
 
108
        if (level == -1) return; /* error in options */
 
109
        if (level == 0) level = MSGLEVEL_ALL;
 
110
 
 
111
        if (g_hash_table_lookup(optlist, "clear") != NULL) {
 
112
                window_lastlog_clear(active_win);
 
113
                if (*searchtext == '\0')
 
114
                        return;
 
115
        }
 
116
 
 
117
        /* which window's lastlog to look at? */
 
118
        window = active_win;
 
119
        str = g_hash_table_lookup(optlist, "window");
 
120
        if (str != NULL) {
 
121
                window = is_numeric(str, '\0') ?
 
122
                        window_find_refnum(atoi(str)) :
 
123
                        window_find_item(NULL, str);
 
124
                if (window == NULL) {
 
125
                        printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
 
126
                                    TXT_REFNUM_NOT_FOUND, str);
 
127
                        return;
 
128
                }
 
129
        }
 
130
 
 
131
        if (g_hash_table_lookup(optlist, "new") != NULL)
 
132
                startline = textbuffer_view_get_bookmark(WINDOW_GUI(window)->view, "lastlog_last_check");
 
133
        else if (g_hash_table_lookup(optlist, "away") != NULL)
 
134
                startline = textbuffer_view_get_bookmark(WINDOW_GUI(window)->view, "lastlog_last_away");
 
135
        else
 
136
                startline = NULL;
 
137
 
 
138
        if (startline == NULL)
 
139
                startline = textbuffer_view_get_lines(WINDOW_GUI(window)->view);
 
140
 
 
141
        str = g_hash_table_lookup(optlist, "#");
 
142
        if (str != NULL) {
 
143
                before = after = atoi(str);
 
144
        } else {
 
145
                str = g_hash_table_lookup(optlist, "before");
 
146
                before = str == NULL ? 0 : *str != '\0' ?
 
147
                        atoi(str) : DEFAULT_LASTLOG_BEFORE;
 
148
 
 
149
                str = g_hash_table_lookup(optlist, "after");
 
150
                if (str == NULL) str = g_hash_table_lookup(optlist, "a");
 
151
                after = str == NULL ? 0 : *str != '\0' ?
 
152
                        atoi(str) : DEFAULT_LASTLOG_AFTER;
 
153
        }
 
154
 
 
155
        list = textbuffer_find_text(WINDOW_GUI(window)->view->buffer, startline,
 
156
                                    level, MSGLEVEL_LASTLOG,
 
157
                                    searchtext, before, after,
 
158
                                    g_hash_table_lookup(optlist, "regexp") != NULL,
 
159
                                    g_hash_table_lookup(optlist, "word") != NULL,
 
160
                                    g_hash_table_lookup(optlist, "case") != NULL);
 
161
 
 
162
        len = g_list_length(list);
 
163
        if (count <= 0)
 
164
                tmp = list;
 
165
        else {
 
166
                int pos = len-count-start;
 
167
                if (pos < 0) pos = 0;
 
168
 
 
169
                tmp = pos > len ? NULL : g_list_nth(list, pos);
 
170
                len = g_list_length(tmp);
 
171
        }
 
172
 
 
173
        if (g_hash_table_lookup(optlist, "count") != NULL) {
 
174
                printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
 
175
                                   TXT_LASTLOG_COUNT, len);
 
176
                g_list_free(list);
 
177
                return;
 
178
        }
 
179
 
 
180
        if (len > MAX_LINES_WITHOUT_FORCE && fhandle == -1 &&
 
181
            g_hash_table_lookup(optlist, "force") == NULL) {
 
182
                printformat_window(active_win,
 
183
                                   MSGLEVEL_CLIENTNOTICE|MSGLEVEL_LASTLOG,
 
184
                                   TXT_LASTLOG_TOO_LONG, len);
 
185
                g_list_free(list);
 
186
                return;
 
187
        }
 
188
 
 
189
        if (fhandle == -1 && g_hash_table_lookup(optlist, "-") == NULL)
 
190
                printformat(NULL, NULL, MSGLEVEL_LASTLOG, TXT_LASTLOG_START);
 
191
 
 
192
        line = g_string_new(NULL);
 
193
        while (tmp != NULL && (count < 0 || count > 0)) {
 
194
                LINE_REC *rec = tmp->data;
 
195
 
 
196
                if (rec == NULL) {
 
197
                        if (tmp->next == NULL)
 
198
                                break;
 
199
                        if (fhandle != -1) {
 
200
                                write(fhandle, "--\n", 3);
 
201
                        } else {
 
202
                                printformat_window(active_win,
 
203
                                                   MSGLEVEL_LASTLOG,
 
204
                                                   TXT_LASTLOG_SEPARATOR);
 
205
                        }
 
206
                        tmp = tmp->next;
 
207
                        continue;
 
208
                }
 
209
 
 
210
                /* get the line text */
 
211
                textbuffer_line2text(rec, fhandle == -1, line);
 
212
                if (!settings_get_bool("timestamps")) {
 
213
                        struct tm *tm = localtime(&rec->info.time);
 
214
                        char timestamp[10];
 
215
 
 
216
                        g_snprintf(timestamp, sizeof(timestamp),
 
217
                                   "%02d:%02d ",
 
218
                                   tm->tm_hour, tm->tm_min);
 
219
                        g_string_prepend(line, timestamp);
 
220
                }
 
221
 
 
222
                /* write to file/window */
 
223
                if (fhandle != -1) {
 
224
                        write(fhandle, line->str, line->len);
 
225
                        write(fhandle, "\n", 1);
 
226
                } else {
 
227
                        printtext_window(active_win, MSGLEVEL_LASTLOG,
 
228
                                         "%s", line->str);
 
229
                }
 
230
 
 
231
                count--;
 
232
                tmp = tmp->next;
 
233
        }
 
234
        g_string_free(line, TRUE);
 
235
 
 
236
        if (fhandle == -1 && g_hash_table_lookup(optlist, "-") == NULL)
 
237
                printformat(NULL, NULL, MSGLEVEL_LASTLOG, TXT_LASTLOG_END);
 
238
 
 
239
        textbuffer_view_set_bookmark_bottom(WINDOW_GUI(window)->view,
 
240
                                            "lastlog_last_check");
 
241
 
 
242
        textbuffer_line_unref_list(WINDOW_GUI(window)->view->buffer, list);
 
243
        g_list_free(list);
 
244
}
 
245
 
 
246
/* SYNTAX: LASTLOG [-] [-file <filename>] [-window <ref#|name>] [-new | -away]
 
247
                   [-<level> -<level...>] [-clear] [-count] [-case]
 
248
                   [-regexp | -word] [-before [<#>]] [-after [<#>]]
 
249
                   [-<# before+after>] [<pattern>] [<count> [<start>]] */
 
250
static void cmd_lastlog(const char *data)
 
251
{
 
252
        GHashTable *optlist;
 
253
        char *text, *countstr, *start, *fname;
 
254
        void *free_arg;
 
255
        int count, fhandle;
 
256
 
 
257
        g_return_if_fail(data != NULL);
 
258
 
 
259
        if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS |
 
260
                            PARAM_FLAG_UNKNOWN_OPTIONS, "lastlog", &optlist,
 
261
                            &text, &countstr, &start))
 
262
                return;
 
263
 
 
264
        if (*start == '\0' && is_numeric(text, 0) && *text != '0' &&
 
265
            (*countstr == '\0' || is_numeric(countstr, 0))) {
 
266
                start = countstr;
 
267
                countstr = text;
 
268
                text = "";
 
269
        }
 
270
        count = atoi(countstr);
 
271
        if (count == 0) count = -1;
 
272
 
 
273
        /* target where to print it */
 
274
        fhandle = -1;
 
275
        fname = g_hash_table_lookup(optlist, "file");
 
276
        if (fname != NULL) {
 
277
                fname = convert_home(fname);
 
278
                fhandle = open(fname, O_WRONLY | O_APPEND | O_CREAT,
 
279
                               octal2dec(settings_get_int("log_create_mode")));
 
280
                g_free(fname);
 
281
        }
 
282
 
 
283
        if (fname != NULL && fhandle == -1) {
 
284
                printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
 
285
                          "%s", g_strerror(errno));
 
286
        } else {
 
287
                show_lastlog(text, optlist, atoi(start), count, fhandle);
 
288
                if (fhandle != -1)
 
289
                        close(fhandle);
 
290
        }
 
291
 
 
292
        cmd_params_free(free_arg);
 
293
}
 
294
 
 
295
void lastlog_init(void)
 
296
{
 
297
        command_bind("lastlog", NULL, (SIGNAL_FUNC) cmd_lastlog);
 
298
 
 
299
        command_set_options("lastlog", "!- # force clear -file -window new away word regexp case count @a @after @before");
 
300
}
 
301
 
 
302
void lastlog_deinit(void)
 
303
{
 
304
        command_unbind("lastlog", (SIGNAL_FUNC) cmd_lastlog);
 
305
}