X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/d6e8d44dbb990fe77f9380ef6cbcd5101807208e..04ee0c3f6ad7e4177cc43a0c57f046013a4fbac9:/uip/mhical.c diff --git a/uip/mhical.c b/uip/mhical.c index 27f7c9f1..402d5ad9 100644 --- a/uip/mhical.c +++ b/uip/mhical.c @@ -1,5 +1,4 @@ -/* - * mhical.c -- operate on an iCalendar request +/* mhical.c -- operate on an iCalendar request * * This code is Copyright (c) 2014, by the authors of nmh. * See the COPYRIGHT file in the root directory of the nmh @@ -7,11 +6,16 @@ */ #include "h/mh.h" +#include "sbr/path.h" +#include "sbr/print_version.h" +#include "sbr/print_help.h" +#include "sbr/error.h" #include "h/icalendar.h" #include "sbr/icalparse.h" -#include +#include "h/fmt_scan.h" #include "h/addrsbr.h" #include "h/mts.h" +#include "h/done.h" #include "h/utils.h" #include @@ -30,7 +34,7 @@ static void convert_common (contentline *, act); static void dump_unfolded (FILE *, contentline *); static void output (FILE *, contentline *, int); static void display (FILE *, contentline *, char *); -static const char *identity (const contentline *); +static const char *identity (const contentline *) PURE; static char *format_params (char *, param_list *); static char *fold (char *, int); @@ -57,9 +61,11 @@ DEFINE_SWITCH_ARRAY(MHICAL, switches); #undef X vevent vevents = { NULL, NULL, NULL}; +int parser_status = 0; int -main (int argc, char *argv[]) { +main (int argc, char *argv[]) +{ /* RFC 5322 § 3.3 date-time format, including the optional day-of-week and not including the optional seconds. The zone is required by the RFC but not always output by this @@ -69,14 +75,15 @@ main (int argc, char *argv[]) { act action = ACT_NONE; char *infile = NULL, *outfile = NULL; FILE *inputfile = NULL, *outputfile = NULL; - int contenttype = 0, unfold = 0; + bool contenttype = false; + bool unfold = false; vevent *v, *nextvevent; char *form = "mhical.24hour", *format = NULL; char **argp, **arguments, *cp; icaldebug = 0; /* Global provided by bison (with name-prefix "ical"). */ - if (nmh_init(argv[0], 2)) { return 1; } + if (nmh_init(argv[0], true, false)) { return 1; } arguments = getarguments (invo_name, argc, argv, 1); argp = arguments; @@ -91,7 +98,7 @@ main (int argc, char *argv[]) { ambigsw (cp, switches); done (1); case UNKWNSW: - adios (NULL, "-%s unknown", cp); + die("-%s unknown", cp); case HELPSW: { char buf[128]; @@ -108,7 +115,7 @@ main (int argc, char *argv[]) { case REPLYSW: if (! (cp = *argp++) || (*cp == '-' && cp[1])) - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); if (! strcasecmp (cp, "accept")) { action = ACT_ACCEPT; } else if (! strcasecmp (cp, "decline")) { @@ -118,7 +125,7 @@ main (int argc, char *argv[]) { } else if (! strcasecmp (cp, "delegate")) { action = ACT_DELEGATE; } else { - adios (NULL, "Unknown action: %s", cp); + die("Unknown action: %s", cp); } continue; @@ -128,35 +135,35 @@ main (int argc, char *argv[]) { case FORMSW: if (! (form = *argp++) || *form == '-') - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); format = NULL; continue; case FMTSW: if (! (format = *argp++) || *format == '-') - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); form = NULL; continue; case INFILESW: if (! (cp = *argp++) || (*cp == '-' && cp[1])) - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); infile = *cp == '-' ? mh_xstrdup(cp) : path (cp, TFILE); continue; case OUTFILESW: if (! (cp = *argp++) || (*cp == '-' && cp[1])) - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); outfile = *cp == '-' ? mh_xstrdup(cp) : path (cp, TFILE); continue; case CONTENTTYPESW: - contenttype = 1; + contenttype = true; continue; case NCONTENTTYPESW: - contenttype = 0; + contenttype = false; continue; case UNFOLDSW: - unfold = 1; + unfold = true; continue; } } @@ -237,7 +244,7 @@ main (int argc, char *argv[]) { free (outfile); } - return 0; + return parser_status; } /* @@ -255,9 +262,10 @@ main (int argc, char *argv[]) { * - Excise VALARM sections. */ static void -convert_to_reply (contentline *clines, act action) { +convert_to_reply (contentline *clines, act action) +{ char *partstat = NULL; - int found_my_attendee_line = 0; + bool found_my_attendee_line = false; contentline *node; convert_common (clines, action); @@ -301,7 +309,7 @@ convert_to_reply (contentline *clines, act action) { while (getname ("")) { continue; } if (ismymbox (mn)) { - found_my_attendee_line = 1; + found_my_attendee_line = true; for (p = node->params; p && p->param_name; p = p->next) { value_list *v; @@ -361,7 +369,8 @@ convert_to_reply (contentline *clines, act action) { * - Excise VALARM sections. */ static void -convert_to_cancellation (contentline *clines) { +convert_to_cancellation (contentline *clines) +{ contentline *node; convert_common (clines, ACT_CANCEL); @@ -383,9 +392,10 @@ convert_to_cancellation (contentline *clines) { } static void -convert_common (contentline *clines, act action) { +convert_common (contentline *clines, act action) +{ contentline *node; - int in_valarm; + bool in_valarm; if ((node = find_contentline (clines, "METHOD", 0))) { free (node->value); @@ -399,13 +409,14 @@ convert_common (contentline *clines, act action) { if ((node = find_contentline (clines, "VERSION", 0))) { if (! node->value) { - admonish (NULL, "Version property is missing value, assume 2.0"); + inform("Version property is missing value, assume 2.0, continuing..."); node->value = mh_xstrdup ("2.0"); } if (strcmp (node->value, "2.0")) { - admonish (NULL, "supports the Version 2.0 specified by RFC 5545 " - "but iCalendar object has Version %s", node->value); + inform("supports the Version 2.0 specified by RFC 5545 " + "but iCalendar object has Version %s, continuing...", + node->value); node->value = mh_xstrdup ("2.0"); } } @@ -424,7 +435,7 @@ convert_common (contentline *clines, act action) { insert = "Tentative: "; break; case ACT_DELEGATE: - adios (NULL, "Delegate replies are not supported"); + die("Delegate replies are not supported"); break; case ACT_CANCEL: insert = "Cancelled:"; @@ -443,7 +454,7 @@ convert_common (contentline *clines, act action) { node->value = tmp; } else { /* Should never get here. */ - adios (NULL, "Unknown action: %d", action); + die("Unknown action: %d", action); } } @@ -460,15 +471,15 @@ convert_common (contentline *clines, act action) { free (node->value); node->value = mh_xstrdup (buf); } else { - admonish (NULL, "strftime unable to format current time"); + inform("strftime unable to format current time, continuing..."); } } else { - admonish (NULL, "gmtime_r failed on current time"); + inform("gmtime_r failed on current time, continuing..."); } } /* Excise X- lines and VALARM section(s). */ - in_valarm = 0; + in_valarm = false; for (node = clines; node; node = node->next) { /* node->name will be NULL if the line was deleted. */ if (! node->name) { continue; } @@ -476,13 +487,13 @@ convert_common (contentline *clines, act action) { if (in_valarm) { if (! strcasecmp ("END", node->name) && ! strcasecmp ("VALARM", node->value)) { - in_valarm = 0; + in_valarm = false; } remove_contentline (node); } else { if (! strcasecmp ("BEGIN", node->name) && ! strcasecmp ("VALARM", node->value)) { - in_valarm = 1; + in_valarm = true; remove_contentline (node); } else if (! strncasecmp ("X-", node->name, 2)) { remove_contentline (node); @@ -493,7 +504,8 @@ convert_common (contentline *clines, act action) { /* Echo the input, but with unfolded lines. */ static void -dump_unfolded (FILE *file, contentline *clines) { +dump_unfolded (FILE *file, contentline *clines) +{ contentline *node; for (node = clines; node; node = node->next) { @@ -502,7 +514,8 @@ dump_unfolded (FILE *file, contentline *clines) { } static void -output (FILE *file, contentline *clines, int contenttype) { +output (FILE *file, contentline *clines, int contenttype) +{ contentline *node; if (contenttype) { @@ -534,11 +547,10 @@ output (FILE *file, contentline *clines, int contenttype) { line = fold (add (node->value, line), clines->cr_before_lf == CR_BEFORE_LF); - if (clines->cr_before_lf == LF_ONLY) { - fprintf (file, "%s\n", line); - } else { - fprintf (file, "%s\r\n", line); - } + fputs(line, file); + if (clines->cr_before_lf != LF_ONLY) + putc('\r', file); + putc('\n', file); free (line); } } @@ -556,10 +568,11 @@ output (FILE *file, contentline *clines, int contenttype) { * - attendees (limited to number specified in initialization) */ static void -display (FILE *file, contentline *clines, char *nfs) { +display (FILE *file, contentline *clines, char *nfs) +{ tzdesc_t timezones = load_timezones (clines); - int in_vtimezone; - int in_valarm; + bool in_vtimezone; + bool in_valarm; contentline *node; struct format *fmt; int dat[5] = { 0, 0, 0, INT_MAX, 0 }; @@ -594,7 +607,7 @@ display (FILE *file, contentline *clines, char *nfs) { } /* Only display DESCRIPTION lines that are outside VALARM section(s). */ - in_valarm = 0; + in_valarm = false; if ((c = fmt_findcomp ("description"))) { for (node = clines; node; node = node->next) { /* node->name will be NULL if the line was deleted. */ @@ -605,12 +618,12 @@ display (FILE *file, contentline *clines, char *nfs) { } else if (in_valarm) { if (! strcasecmp ("END", node->name) && ! strcasecmp ("VALARM", node->value)) { - in_valarm = 0; + in_valarm = false; } } else { if (! strcasecmp ("BEGIN", node->name) && ! strcasecmp ("VALARM", node->value)) { - in_valarm = 1; + in_valarm = true; } } } @@ -625,7 +638,7 @@ display (FILE *file, contentline *clines, char *nfs) { if ((c = fmt_findcomp ("dtstart"))) { /* Find DTSTART outsize of a VTIMEZONE section. */ - in_vtimezone = 0; + in_vtimezone = false; for (node = clines; node; node = node->next) { /* node->name will be NULL if the line was deleted. */ if (! node->name) { continue; } @@ -633,12 +646,12 @@ display (FILE *file, contentline *clines, char *nfs) { if (in_vtimezone) { if (! strcasecmp ("END", node->name) && ! strcasecmp ("VTIMEZONE", node->value)) { - in_vtimezone = 0; + in_vtimezone = false; } } else { if (! strcasecmp ("BEGIN", node->name) && ! strcasecmp ("VTIMEZONE", node->value)) { - in_vtimezone = 1; + in_vtimezone = true; } else if (! strcasecmp ("DTSTART", node->name)) { /* Got it: DTSTART outside of a VTIMEZONE section. */ char *datetime = format_datetime (timezones, node); @@ -713,7 +726,7 @@ display (FILE *file, contentline *clines, char *nfs) { } /* Don't call on the END:VCALENDAR line. */ - if (clines->next) { + if (clines && clines->next) { (void) fmt_scan (fmt, buffer, INT_MAX, dat, NULL); fputs (charstring_buffer (buffer), file); fmt_free (fmt, 1); @@ -725,7 +738,8 @@ display (FILE *file, contentline *clines, char *nfs) { } static const char * -identity (const contentline *node) { +identity (const contentline *node) +{ /* According to RFC 5545 § 3.3.3, an email address in the value must be a mailto URI. */ if (! strncasecmp (node->value, "mailto:", 7)) { @@ -755,7 +769,8 @@ identity (const contentline *node) { } static char * -format_params (char *line, param_list *p) { +format_params (char *line, param_list *p) +{ for ( ; p && p->param_name; p = p->next) { value_list *v; size_t num_values = 0; @@ -788,7 +803,8 @@ format_params (char *line, param_list *p) { } static char * -fold (char *line, int uses_cr) { +fold (char *line, int uses_cr) +{ size_t remaining = strlen (line); size_t current_line_len = 0; charstring_t folded_line = charstring_create (2 * remaining); @@ -809,7 +825,7 @@ fold (char *line, int uses_cr) { #endif charstring_push_back_chars (folded_line, cp, char_len, 1); - remaining -= char_len > 0 ? char_len : 1; + remaining -= max(char_len, 1); /* remaining must be > 0 to pass the loop condition above, so if it's not > 1, it is == 1. */ @@ -824,7 +840,7 @@ fold (char *line, int uses_cr) { } } - cp += char_len > 0 ? char_len : 1; + cp += max(char_len, 1); } free (line);