| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
| |
The function day_process_storage() is a wrapper for day_store_items().
It has an unused second argument, and is only used twice to load the
selected day. It has been removed.
A new function, get_slctd_day(), is the equivalant of get_today() and
replaces the very awkwardly named ui_calendar_get_slctd_day_sec().
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The changes are related to the selected item and the visible lines in
the scroll window viewport.
In particular, the function listbox_fix_visible_region() has been
eliminated, and functions previously only called by it have been
removed. It performed several tasks that are now elsewhere. One was
removed in an earlier commit (scroll window pad improvement). The task
of making a multi-line item visible has been moved to
listbox_item_in_view(). The task of making a caption line above a text
line visible is listbox specific (for the ap_list) and will be moved to
ui_day_sel_move(), where it is needed.
Boundary checks for the listbox selection have been moved to
listbox_fix_sel().
For future use listbox_sel_move() returns success or failure.
The function wins_scrollwin_ensure_visible() has been renamed
wins_scrollwin_in_view().
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A scroll window consists of a pad to write on, and a window through
which to view the pad, the viewport. The pad may change in size when new
contents are loaded into the scroll window. If so, the pad size is set
with wins_scrollwin_set_linecount(). But the offset into the pad (the
top line to be displayed in the viewport) is not adjusted, although it
may not be appropriate for the new pad size. The same is the case when a
scroll window is resized and the viewport changes size. This is probably
the cause of the problem solved by commit 0b46ad4, Avoid blank space
after the last list box item, and the fix has been removed.
The wins_scrollwin_set_linecount() has been renamed
wins_scrollwin_set_pad() and sets size as well as offset. The offset is
only changed if necessary.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
| |
The exception days are presented for viewing/editing as a string of
space-separated dates (in the user-preferred input format). After
editing the string is checked for valid dates, but there is no check
that a date is meaningful (an occurrence day of the item between start
day and until day). Although possible, it is best to add exception days
in the usual way by deletion of occurrences.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
| |
The %-d format string is not standards-compliant. Use %e instead.
Reported-by: Mikolaj Kucharski <mikolaj@kucharski.name>
Suggested-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
| |
Included is a check of the 'until' date for pasted recurrent items.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
| |
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Recurring appointments do not show up in the notification bar as next
appointment. This was partly corrected by 2084f35 (Fix notification of
recurrent appointments, 2017-02-09) and 5aa7a09 (Fix another error in
the notification code, 2017-02-11).
The search function recur_apoint_starts_before() had a wrong second
argument, but is really of no use: the start time of a recurring
appointment is the start time of the very first occurrence (in the
past). A comparison against the item in the notify_app structure tells
nothing of the start time of the current day; at most it eliminates some
future recurring appointments. The function can be dropped, and the
entire recurring appointment list looked through.
The proper start time is found in the main search loop (and called
real_recur_start_time) and must be compared against the item in the
notify_app structure.
But because recur_apoint_find_occurrence() is limited to a particular
day (second argument), two searches are necessary to cover 24 hours.
Unrelated cleanups: removed function return value; changed long to
time_t.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The configuration settings for calendar view (monthly/weekly) and todo
view (hide/show completed) used to be saved automatically on calcurse
exit, with values taken from the current interactive settings. They
could not be set explicitly in the configuration menues. Configuration
settings are no longer saved on program exit, but on exit from the
configuration menu. This means that the saved values are those that were
current when the configuration menu was entered. To change a saved
value, you must set the view as desired and then enter/exit the
configuration menu.
The preferred calendar and todo views are no longer automatically taken
from the interactive settings, but are explicitly set in the general
options menu. Default values are monthly view and hide completed view.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
New filter option: --filter-invert. When present it inverts (negates)
the other filter options combined. This is mostly useful with the -G
option (with -Q the output is limited by the query range (day range)).
The ouput from "calcurse -G <filter options>" is the (set) complement of
"calcurse -G <filter options> --filter-invert". Here <filter options>
may be any combination of filter options.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
An earlier commit ("CLI: take input date format from configuration file,
do not accept time") replaced parse_datetimearg() with parse_datearg()
and eliminated time-of-day from command line date arguments. This made
the full use of filter options impossible.
That earlier commit is reverted and updated. The parse_datearg()
function is replaced by an updated parse_datetimearg() function that
- takes the date format from the configuration file
- accepts date, date-time or time
The updated parse_datetimearg() function has been extended to report
back the type of the date string received in order to set (filter)
options correctly. Input dates for query ranges (--from, --to, --days)
are still limited to dates only.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The introduction of the "-C <confdir>" option is an opportunity to
review the initialization of data paths. It lead to a rewrite.
Two "root" directories are used (data and configuration files); by
default they are identical. The statically allocated path buffers are
turned into dynamically allocated buffers.
Missing files/directories now include hooks.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The number of seconds in a day and daylength in seconds differ when
Daylight Saving Time is in effect on two days of the year. The day when DST
takes effect is 23 hours long, and the day when DST ends is 25 hours long.
In the latter case the date changing thread wóuld enter a loop in the last hour
before midnight (in the former it would set the date an hour too late).
The next midnight is calculated through mktime(), invoked by date2sec().
Wrong daylength prevented appointments from being stored in the day vector and
caused them to be displayed wrongly in the appts panel.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
| |
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
| |
After user acknowledgement a system event is deleted from the event queue.
The configuration variable determines whether it is turned into an appointment
(for later inspection) or not.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The screen and user interaction is managed by the main thread. Other parts of
calcurse (threads) wishing to use the screen or communicate with the user, must
do it via the main thread.
For this purpose the main input loop is extended with a message queue. A thread
may insert a message in the queue. The main thread tests for messages before
listening for user commands. If a message is present, it is displayed (in a popup
window) for the user to acknowledge. Depending on the message other actions may
be performed, e.g. the message could be turned into a "system appointment/event"
and inserted among the usual appointments.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
| |
When loading/saving the configuration file the entry is silently ignored
(which means it is removed by the first save).
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
| |
The return code from new_data() and io_load_data() is explicitly defined as a
bit mask. A file access error is recognised and reported back to the user.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
| |
A new argument to io_save_cal() makes it possible for the periodic save thread
to avoid 1) user interaction and 2) overwriting new data.
At the moment the thread has no way to report on the result of the save.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The function io_save_cal() saves apts, todos, configuration data and key
bindings. The configuration and key files do not belong with the two data
files, but the progress bar function assumes that all four files are saved in
a fixed sequence. Since it is used nowhere else and contains unused parts,
the function has been removed.
A return code for file access error is introduced, and the EXIT macro moved to
the command level in calcurse.c.
Save of configuration and key data were already moved to the configuration menu
in commit 0124618, A save refinement: no action if everything is unchanged.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Moving user information to calcurse.c makes it easier to perform the actual
save/reload operatons in io.c, e.g. it is possible to load instead of
reload after a merge in conflict resolving.
The save/reload operations are of such importance that the user should always be
informed of the result (it's a bit disquieting when there is no reaction to a
save or reload command). Hence, the save/reload status messages are no longer
conditioned by show_dialogs(). No confirmation is asked for, so a message stays
until the status bar is updated by another action.
Care is taken to inform about save/reload actions that result in no change.
Texts are kept concise because of the limited message area. When conflicts are
present, whether saving or reloading, the "continue/merge/cancel" pattern seems
easier to grasp.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a replacement for commits 57dd3d6 and 912124b.
The idea is to move the check for modified files and the list initialization
into io_load_data(), and let io_load_data() decide what to load. A new
argument is used to force a load.
The return code from new_data() (the renamed version of
io_check_data_files_modified()) tells which files have changed.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
After resolving a save conflict with the merge tool, a save operation has,
in effect, occurred, and data files must be reloaded to import the result of
the conflict resolution.
This is a replacement for commit 2fe9c7e. The operations concerned with the user
interface are kept out the io-operations (as in all other cases) and take place
at the command-level in calcurse.c. and not at the io-level (io.c).
Shorter, more concise prompt texts.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
| |
All appointment times are checked for validity. Overflow by time
arithmetic is detected. End times are checked when appointments
are moved. Three functions are involved: parse_datetime(),
parse_duration() and parse_date_duration(); they all have a
new argument for validation purposes.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
| |
check_sec(), overflow_add(), overflow_mul()
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
calcurse deadlocks when
1) an upcoming appointment is on display in the notification bar,
2) an external command (like help) is started,
3) the time for the upcoming appointment arrives, and
4) the external command is exited.
The notification bar thread is stopped while the external command is
running. Upon exit from the external command, the n-bar thread is
restarted and calcurse locks.
The cause is the way in which the main notification bar thread is
stopped:
static pthread_t notify_t_main;
void notify_stop_main_thread(void)
{
if (notify_t_main) {
pthread_cancel(notify_t_main);
pthread_join(notify_t_main, NULL);
}
}
Objects of type pthread_t are opaque and should not be accessed
directly. Initially notify_t_main is an uninitialised static variable
(0), but later it has a value, which may or may not be the thread id of
the notification main thread.
Note that the thread id after exit of a thread may become the thread id
of a new thread. Thus the variable set when the thread is created, is
invalid after exit of the thread.
Specifically, the first time notify_stop_main_thread() is called (by
notify_start_main_thread() before the thread is created) is harmless
(because notify_t_main is 0). Calling notify_stop_main_thread() later
may be either
OK
because the main thread is running, or
harmless
because no thread with id notify_t_main is running: the two
functions will fail with return value ESRCH (no such process), or
fatal
because an unrelated thread with this thread id is running: it will
be cancelled, and the join may or may not succeed depending on
whether the thread is joinable or detached.
The "unrelated thread" could be the next-appointment thread,
notify_thread_app, launched by notify_check_next_app().
Always calling notify_stop_main_thread() before starting the main thread
becomes fatal when notify_check_next_app() is called shortly before
notify_start_main_thread(). This is the case in the scenario described.
The next-app-thread is then running when notify_stop_main_thread() is
called, and apparently it has the thread id of the old main thread
(confirmed by logging the return values from pthread_cancel() and
pthread_join(); the first succeeds while the second fails with EINVALID
which means that the thread is not joinable). The next-app-thread will
therefore exit without unlocking mutexes.
Ensure that notify_t_main, in case the notify main thread is not
running, has a value that it will never have when it is running. A
possibility is the thread id of the main() calcurse process (returned by
pthread_self()).
Check for this condition in notify_stop_main_thread() and set
notify_t_main when the thread is stopped.
Similar changes have been introduced for the periodic save thread and
the calendar date thread.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Internally characters (keys) have two representations: integers and key
names. Key names are characters strings, usually the name of the
character; e.g., the character A has the representations 65 and "A", and
the tab character the representations 9 and "TAB".
The function keys_int2str() turns the integer representation of a
key/character into the key name.
For display purposes the key names are usually confined to have display
width at most three. Some curses pseudo-keys have longer key names;
e.g., the back-tab character is "KEY_BTAB". A long key name makes a
character difficult to recognize in the status bar menu.
The key name of a multibyte, UTF-8 encoded character is the conventional
Unicode name of the code point; e.g., the character ü has key name
"U+00FC" because ü is the code point 0xFC. Most of these look alike in
the status bar menu.
The patch makes the key name of a multibyte character look like that of
a singlebyte character: the character itself, i.e. the key name of the
character ü is "ü".
The main tool is implementation of a utf8_encode() routine.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
| |
Purely for readability and in preparation for the counterpart utf8_encode().
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
| |
The configuration file (~/.calcurse/conf by default) can now be
specified with -C or --conf.
Workaround for GitHub issue #86.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a scrollbar is on display in APP or TOD windows, the right
vertical border (outside the scrollbar) is not highlighted
when the window is selected.
The scrollbar is always highlighted:
- when APP or TOD is deselected
- in configuration windows where borders otherwise are not
The patch moves the scrollbar parameters (except highlight)
from arguments of draw_scrollbar() to the function itself.
The highlight argument was 1; instead it is set higher in
the call hierarchy (wins_update_panels()) and passed on down.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a scrollbar is on display in APP or TOD windows, the right
vertical border (outside the scrollbar) is not highlighted
when the window is selected.
The scrollbar itself is always highlighted:
- when APP or TOD is deselected
- in configuration windows where borders otherwise are not
The patch moves the scrollbar parameters from arguments of
draw_scrollbar() to the function itself.
The highlight argument to draw_scrollbar() was always 1.
Instead call circumstances are figured out and highlight set
accordingly.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the default colour setup (white on black), white could only
with great difficulty be used as customized foreground colour,
because the colour pair COLR_CUSTOM then was identical to
COLR_DEFAULT (default on default). This made it impossible to
distinguish the selected element in lists.
The patch turns on the video attribute bold when default is chosen
as foreground colour.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
| |
UTF-8 encodes characters in one to four bytes (since 2003).
Because 0 is a valid code point, the decode function utf8_ord()
should return -1, not 0, on error. As a consequence utf8_width()
should return 0 for a continuation byte (as it did previously).
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Reintroduce year check for systems with a 32-bit time_t type. Remove the
lower limit (1902) for systems with a 64-bit time_t. This limits
movements in the calendar (for 32-bit systems) and in no way ensures
constistency of data.
Commit a12833e (Handle dates past January 19th, 2038, 2015-01-19)
removed the upper limit (2037) on dates but left the lower limit (1902).
It did not ensure the support of the target system.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
| |
Remove two remnants: custom_color_theme_name() and custom_set_swsiz().
Make static and rename custom_confwin_init() into confwin_init().
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
| |
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
| |
The window was not deleted if an "already in use"-key was detected,
and a new one was created as the loop was reentered.
Create/delete of the popup are moved outside the loop.
A redrawwin() call is needed to have the window displayed again.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
| |
Add a wrapper around parse_date() which picks the current input date
format as well as the currently selected day and passes both values to
parse_date(), alongside with the parameters passed to
parse_date_interactive() itself.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
| |
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
All key names for ordinary ASCII keys as well as for escape keys (pseudo
keys) are cached in a lookup-table, keynames[], at startup. Mapping
between key names (strings) and key codes (integers) in keys_str2int and
keys_int2str) is performed through this table.
The key names used are those returned by the keyname() function of
ncurses. But to accommodate some of the names to the three-letter space
available in the status menu, four ordinary keys and the most common
escape keys have calcurse abbreviated names: ESC, TAB, RET, SPC and LFT,
HOM, PgU, INS, F1, etc.
All keys known by ncurses can be bound. Thus the check for not
recognized keys in the key configuration menu becomes superfluous. The
only keys that cannot be bound, are those escape keys not known to
ncurses, i.e. not described by the terminfo database for the terminal
type in use.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
| |
Replace the save mutex with a common mutex, which is locked whenever
read or write operations on the data files are performed. Also, since
this mutex is an implementation detail, mark the locking functions
static and remove them from the header file.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
| |
Instead of blindly reloading data in io_reload_data(), compare the
stored hashes of the data files with hashes of the current file contents
and only reload if any of the hashes differs.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
| |
The date at the top of the appointments list may be positioned either to
the left, in the middle or to the right. Default is to the right. Can be
configured from the general options menu.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
| |
The computation never really worked before and it seems like the feature
is not very helpful, sometimes even confusing (see GitHub issue #21).
The macro ISLEAP is moved to calcurse.h.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
| |
Introduce a new function keys_wait_for_any_key() and use it instead of
wgetch() whenever the return value is discarded.
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A new function keys_wgetch() reads full UTF-8 characters instead of
single ASCII characters only.
Key bindings for regular ASCII characters are stored in a hash map while
the actions of keys with higher code points are stored in a linked list
for space efficiency.
The key serialization methods are updated to handle UTF-8 characters as
well; extended UTF-8 characters (characters not in the ASCII range) are
serialized by using the hexadecimal representation of the corresponding
code points (e.g. "U+00E4").
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
| |
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
| |
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
| |
Use the locale setting to fetch the month names and abbreviated day
names.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|
|
|
|
|
|
|
|
| |
Add a new configuration variable format.dayheading to set the format of
the date displayed at the top of the event and appointment list.
Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
|