13 #include <sys/types.h>
15 #include <sys/socket.h>
17 #include <netinet/in.h>
27 #include "webserver.h"
30 "January", "February", "March", "April", "May", "June", "July",
31 "August", "September", "October", "November", "December"
35 "Sunday", "Monday", "Tuesday", "Wednesday",
36 "Thursday", "Friday", "Saturday"
40 "12am", "1am", "2am", "3am", "4am", "5am", "6am",
41 "7am", "8am", "9am", "10am", "11am", "12pm",
42 "1pm", "2pm", "3pm", "4pm", "5pm", "6pm",
43 "7pm", "8pm", "9pm", "10pm", "11pm"
46 #ifdef WEBCIT_WITH_CALENDAR_SERVICE
49 * The display_icaltimetype_as_webform() and icaltime_from_webform() functions
50 * handle the display and editing of date/time properties in web pages. The
51 * first one converts an icaltimetype into valid HTML markup -- a series of form
52 * fields for editing the date and time. When the user submits the form, the
53 * results can be fed back into the second function, which turns it back into
54 * an icaltimetype. The "prefix" string required by both functions is prepended
55 * to all field names. This allows a form to contain more than one date/time
56 * property (for example, a start and end time) by ensuring the field names are
57 * unique within the form.
59 * NOTE: These functions assume that the icaltimetype being edited is in UTC, and
60 * will convert to/from local time for editing. "local" in this case is assumed
61 * to be the time zone in which the WebCit server is running. A future improvement
62 * might be to allow the user to specify his/her timezone.
66 void display_icaltimetype_as_webform(struct icaltimetype *t, char *prefix) {
74 int all_day_event = 0;
77 localtime_r(&now, &tm_now);
78 this_year = tm_now.tm_year + 1900;
80 if (t == NULL) return;
81 if (t->is_date) all_day_event = 1;
82 tt = icaltime_as_timet(*t);
87 localtime_r(&tt, &tm);
91 wprintf("<SELECT NAME=\"%s_month\" SIZE=\"1\">\n", prefix);
92 for (i=0; i<=11; ++i) {
93 wprintf("<OPTION %s VALUE=\"%d\">%s</OPTION>\n",
94 ((tm.tm_mon == i) ? "SELECTED" : ""),
99 wprintf("</SELECT>\n");
102 wprintf("<SELECT NAME=\"%s_day\" SIZE=\"1\">\n", prefix);
103 for (i=1; i<=31; ++i) {
104 wprintf("<OPTION %s VALUE=\"%d\">%d</OPTION>\n",
105 ((tm.tm_mday == i) ? "SELECTED" : ""),
109 wprintf("</SELECT>\n");
112 wprintf("<SELECT NAME=\"%s_year\" SIZE=\"1\">\n", prefix);
113 if ((this_year - t->year) > span) {
114 wprintf("<OPTION SELECTED VALUE=\"%d\">%d</OPTION>\n",
117 for (i=(this_year-span); i<=(this_year+span); ++i) {
118 wprintf("<OPTION %s VALUE=\"%d\">%d</OPTION>\n",
119 ((t->year == i) ? "SELECTED" : ""),
123 if ((t->year - this_year) > span) {
124 wprintf("<OPTION SELECTED VALUE=\"%d\">%d</OPTION>\n",
127 wprintf("</SELECT>\n");
130 wprintf("<SELECT NAME=\"%s_hour\" SIZE=\"1\">\n", prefix);
131 for (i=0; i<=23; ++i) {
132 wprintf("<OPTION %s VALUE=\"%d\">%s</OPTION>\n",
133 ((tm.tm_hour == i) ? "SELECTED" : ""),
137 wprintf("</SELECT>\n");
140 wprintf("<SELECT NAME=\"%s_minute\" SIZE=\"1\">\n", prefix);
141 for (i=0; i<=59; ++i) {
142 if ( (i % 5 == 0) || (tm.tm_min == i) ) {
143 wprintf("<OPTION %s VALUE=\"%d\">:%02d</OPTION>\n",
144 ((tm.tm_min == i) ? "SELECTED" : ""),
149 wprintf("</SELECT>\n");
153 struct icaltimetype icaltime_from_webform(char *prefix) {
154 struct icaltimetype t;
160 localtime_r(&tt, &tm);
162 sprintf(vname, "%s_month", prefix); tm.tm_mon = atoi(bstr(vname)) - 1;
163 sprintf(vname, "%s_day", prefix); tm.tm_mday = atoi(bstr(vname));
164 sprintf(vname, "%s_year", prefix); tm.tm_year = atoi(bstr(vname)) - 1900;
165 sprintf(vname, "%s_hour", prefix); tm.tm_hour = atoi(bstr(vname));
166 sprintf(vname, "%s_minute", prefix); tm.tm_min = atoi(bstr(vname));
169 t = icaltime_from_timet(tt, 0);
170 t = icaltime_normalize(t);
176 * Generate a new, globally unique UID parameter for a calendar object.
178 void generate_new_uid(char *buf) {
181 sprintf(buf, "%ld-%d@%s",
184 serv_info.serv_fqdn);
188 * Render a PARTSTAT parameter as a string (and put it in parentheses)
190 void partstat_as_string(char *buf, icalproperty *attendee) {
191 icalparameter *partstat_param;
192 icalparameter_partstat partstat;
194 strcpy(buf, "(status unknown)");
196 partstat_param = icalproperty_get_first_parameter(
198 ICAL_PARTSTAT_PARAMETER
200 if (partstat_param == NULL) {
204 partstat = icalparameter_get_partstat(partstat_param);
206 case ICAL_PARTSTAT_X:
209 case ICAL_PARTSTAT_NEEDSACTION:
210 strcpy(buf, "(needs action)");
212 case ICAL_PARTSTAT_ACCEPTED:
213 strcpy(buf, "(accepted)");
215 case ICAL_PARTSTAT_DECLINED:
216 strcpy(buf, "(declined)");
218 case ICAL_PARTSTAT_TENTATIVE:
219 strcpy(buf, "(tenative)");
221 case ICAL_PARTSTAT_DELEGATED:
222 strcpy(buf, "(delegated)");
224 case ICAL_PARTSTAT_COMPLETED:
225 strcpy(buf, "(completed)");
227 case ICAL_PARTSTAT_INPROCESS:
228 strcpy(buf, "(in process)");
230 case ICAL_PARTSTAT_NONE:
231 strcpy(buf, "(none)");
238 * Utility function to encapsulate a subcomponent into a full VCALENDAR
240 icalcomponent *ical_encapsulate_subcomponent(icalcomponent *subcomp) {
241 icalcomponent *encaps;
243 lprintf(9, "ical_encapsulate_subcomponent() called\n");
245 if (subcomp == NULL) {
246 lprintf(3, "ERROR: called with NULL argument!\n");
250 /* If we're already looking at a full VCALENDAR component,
251 * don't bother ... just return itself.
253 if (icalcomponent_isa(subcomp) == ICAL_VCALENDAR_COMPONENT) {
254 lprintf(9, "Already encapsulated. Returning itself.\n");
258 /* Encapsulate the VEVENT component into a complete VCALENDAR */
259 encaps = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
260 if (encaps == NULL) {
261 lprintf(3, "Error at %s:%d - could not allocate component!\n",
266 /* Set the Product ID */
267 icalcomponent_add_property(encaps, icalproperty_new_prodid(PRODID));
269 /* Set the Version Number */
270 icalcomponent_add_property(encaps, icalproperty_new_version("2.0"));
272 /* Encapsulate the subcomponent inside */
273 lprintf(9, "Doing the encapsulation\n");
274 icalcomponent_add_component(encaps, subcomp);
276 /* Convert all timestamps to UTC so we don't have to deal with
277 * stupid VTIMEZONE crap.
279 ical_dezonify(encaps);
281 /* Return the object we just created. */