int main() { icalarray *builtin_timezones; icaltimetype tt; int dd, hh, zz, tried = 0; long zz2 = -1; set_zone_directory("../../zoneinfo"); icaltimezone_set_tzid_prefix("/softwarestudio.org/"); tt = icaltime_current_time_with_zone(icaltimezone_get_builtin_timezone("America/New_York")); tt.year = 2038; (void)icaltime_as_timet_with_zone(tt, icaltimezone_get_builtin_timezone("PST")); tried++; tt.year = 2050; (void)icaltime_as_timet_with_zone(tt, icaltimezone_get_builtin_timezone("PST")); tried++; tt.year = 1958; (void)icaltime_as_timet_with_zone(tt, icaltimezone_get_builtin_timezone("PST")); tried++; builtin_timezones = icaltimezone_get_builtin_timezones(); printf("got %lu zones\n", (unsigned long)builtin_timezones->num_elements); if (builtin_timezones->num_elements == 0) { printf("YIKES. Try running from the build/bin directory\n"); return(1); } for (zz = -1; zz < (int)builtin_timezones->num_elements; zz++) { icaltimezone *zone; if (zz < 0) { zone = icaltimezone_get_utc_timezone(); } else { zone = icalarray_element_at(builtin_timezones, (size_t)zz); } tt = icaltime_current_time_with_zone(zone); for (dd = 0; dd < 370; dd += 17) { for (hh = 0; hh < 60 * 60 * 24; hh += 567) { int zz2cnt; icaltime_adjust(&tt, 0, 0, 0, 1); for (zz2cnt = 0; zz2cnt < 15; zz2cnt++) { icaltimezone *zone2; if (zz2 < 0) { zone2 = icaltimezone_get_utc_timezone(); } else { zone2 = icalarray_element_at(builtin_timezones, (size_t)zz2); } (void)icaltime_as_timet_with_zone(tt, zone2); tried++; zz2++; if (zz2 >= (long)builtin_timezones->num_elements) zz2 = -1; } } } printf("\r%lu %% done", (zz >= 0 ? zz : 0) * 100 / (unsigned long)builtin_timezones->num_elements); fflush(stdout); } printf("\ntried %d times\n", tried); return 0; }
/* * Here's where it all begins. */ int main(int argc, char **argv) { uid_t UID = -1; size_t basesize = 2; /* how big should strbufs be on creation? */ pthread_t SessThread; /* Thread descriptor */ pthread_attr_t attr; /* Thread attributes */ int a; /* General-purpose variable */ char ip_addr[256]="*"; int relh=0; int home=0; char relhome[PATH_MAX]=""; char webcitdir[PATH_MAX] = DATADIR; char *pidfile = NULL; char *hdir; const char *basedir = NULL; char uds_listen_path[PATH_MAX]; /* listen on a unix domain socket? */ const char *I18nDumpFile = NULL; WildFireInitBacktrace(argv[0], 2); start_modules(); #ifdef DBG_PRINNT_HOOKS_AT_START /* dbg_PrintHash(HandlerHash, nix, NULL);*/ #endif /* Ensure that we are linked to the correct version of libcitadel */ if (libcitadel_version_number() < LIBCITADEL_VERSION_NUMBER) { fprintf(stderr, " You are running libcitadel version %d\n", libcitadel_version_number() ); fprintf(stderr, "WebCit was compiled against version %d\n", LIBCITADEL_VERSION_NUMBER ); return(1); } strcpy(uds_listen_path, ""); /* Parse command line */ #ifdef HAVE_OPENSSL while ((a = getopt(argc, argv, "u:h:i:p:t:T:B:x:g:dD:G:cfsS:Z:v:")) != EOF) #else while ((a = getopt(argc, argv, "u:h:i:p:t:T:B:x:g:dD:G:cfZ:v:")) != EOF) #endif switch (a) { case 'u': UID = atol(optarg); break; case 'h': hdir = strdup(optarg); relh=hdir[0]!='/'; if (!relh) { safestrncpy(webcitdir, hdir, sizeof webcitdir); } else { safestrncpy(relhome, relhome, sizeof relhome); } /* free(hdir); TODO: SHOULD WE DO THIS? */ home=1; break; case 'd': running_as_daemon = 1; break; case 'D': pidfile = strdup(optarg); running_as_daemon = 1; break; case 'g': default_landing_page = strdup(optarg); break; case 'B': /* Basesize */ basesize = atoi(optarg); if (basesize > 2) StartLibCitadel(basesize); break; case 'i': safestrncpy(ip_addr, optarg, sizeof ip_addr); break; case 'p': http_port = atoi(optarg); if (http_port == 0) { safestrncpy(uds_listen_path, optarg, sizeof uds_listen_path); } break; case 't': /* no longer used, but ignored so old scripts don't break */ break; case 'T': LoadTemplates = atoi(optarg); dbg_analyze_msg = (LoadTemplates & (1<<1)) != 0; dbg_backtrace_template_errors = (LoadTemplates & (1<<2)) != 0; break; case 'Z': DisableGzip = 1; break; case 'x': /* no longer used, but ignored so old scripts don't break */ break; case 'f': follow_xff = 1; break; case 'c': server_cookie = malloc(256); if (server_cookie != NULL) { safestrncpy(server_cookie, "Set-cookie: wcserver=", 256); if (gethostname (&server_cookie[strlen(server_cookie)], 200) != 0) { syslog(LOG_INFO, "gethostname: %s", strerror(errno)); free(server_cookie); } } break; #ifdef HAVE_OPENSSL case 's': is_https = 1; break; case 'S': is_https = 1; ssl_cipher_list = strdup(optarg); break; #endif case 'G': DumpTemplateI18NStrings = 1; I18nDump = NewStrBufPlain(HKEY("int templatestrings(void)\n{\n")); I18nDumpFile = optarg; break; case 'v': verbose=1; break; default: fprintf(stderr, "usage:\nwebcit " "[-i ip_addr] [-p http_port] " "[-c] [-f] " "[-T Templatedebuglevel] " "[-d] [-Z] [-G i18ndumpfile] " "[-u uid] [-h homedirectory] " "[-D daemonizepid] [-v] " "[-g defaultlandingpage] [-B basesize] " #ifdef HAVE_OPENSSL "[-s] [-S cipher_suites]" #endif "[remotehost [remoteport]]\n"); return 1; } /* Start the logger */ openlog("webcit", ( running_as_daemon ? (LOG_PID) : (LOG_PID | LOG_PERROR) ), LOG_DAEMON ); if (optind < argc) { ctdlhost = argv[optind]; if (++optind < argc) ctdlport = argv[optind]; } /* daemonize, if we were asked to */ if (!DumpTemplateI18NStrings && running_as_daemon) { start_daemon(pidfile); } else { signal(SIGINT, graceful_shutdown); signal(SIGHUP, graceful_shutdown); } webcit_calc_dirs_n_files(relh, basedir, home, webcitdir, relhome); LoadMimeBlacklist(); LoadIconDir(static_icon_dir); /* Tell 'em who's in da house */ syslog(LOG_NOTICE, "%s", PACKAGE_STRING); syslog(LOG_NOTICE, "Copyright (C) 1996-2015 by the citadel.org team"); syslog(LOG_NOTICE, " "); syslog(LOG_NOTICE, "This program is open source software: you can redistribute it and/or"); syslog(LOG_NOTICE, "modify it under the terms of the GNU General Public License, version 3."); syslog(LOG_NOTICE, " "); syslog(LOG_NOTICE, "This program is distributed in the hope that it will be useful,"); syslog(LOG_NOTICE, "but WITHOUT ANY WARRANTY; without even the implied warranty of"); syslog(LOG_NOTICE, "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"); syslog(LOG_NOTICE, "GNU General Public License for more details."); syslog(LOG_NOTICE, " "); /* initialize various subsystems */ initialise_modules(); initialise2_modules(); InitTemplateCache(); if (DumpTemplateI18NStrings) { FILE *fd; StrBufAppendBufPlain(I18nDump, HKEY("}\n"), 0); if (StrLength(I18nDump) < 50) { syslog(LOG_INFO, "*******************************************************************\n"); syslog(LOG_INFO, "* No strings found in templates! Are you sure they're there? *\n"); syslog(LOG_INFO, "*******************************************************************\n"); return -1; } fd = fopen(I18nDumpFile, "w"); if (fd == NULL) { syslog(LOG_INFO, "***********************************************\n"); syslog(LOG_INFO, "* unable to open I18N dumpfile [%s] *\n", I18nDumpFile); syslog(LOG_INFO, "***********************************************\n"); return -1; } fwrite(ChrPtr(I18nDump), 1, StrLength(I18nDump), fd); fclose(fd); return 0; } /* Tell libical to return an error instead of aborting if it sees badly formed iCalendar data. */ icalerror_errors_are_fatal = 0; /* Use our own prefix on tzid's generated from system tzdata */ icaltimezone_set_tzid_prefix("/citadel.org/"); /* * Set up a place to put thread-specific data. * We only need a single pointer per thread - it points to the * wcsession struct to which the thread is currently bound. */ if (pthread_key_create(&MyConKey, NULL) != 0) { syslog(LOG_EMERG, "Can't create TSD key: %s", strerror(errno)); } InitialiseSemaphores(); /* * Set up a place to put thread-specific SSL data. * We don't stick this in the wcsession struct because SSL starts * up before the session is bound, and it gets torn down between * transactions. */ #ifdef HAVE_OPENSSL if (pthread_key_create(&ThreadSSL, NULL) != 0) { syslog(LOG_EMERG, "Can't create TSD key: %s", strerror(errno)); } #endif /* * Bind the server to our favorite port. * There is no need to check for errors, because webcit_tcp_server() * exits if it doesn't succeed. */ if (!IsEmptyStr(uds_listen_path)) { syslog(LOG_DEBUG, "Attempting to create listener socket at %s...", uds_listen_path); msock = webcit_uds_server(uds_listen_path, LISTEN_QUEUE_LENGTH); } else { syslog(LOG_DEBUG, "Attempting to bind to port %d...", http_port); msock = webcit_tcp_server(ip_addr, http_port, LISTEN_QUEUE_LENGTH); } if (msock < 0) { ShutDownWebcit(); return -msock; } syslog(LOG_INFO, "Listening on socket %d", msock); signal(SIGPIPE, SIG_IGN); pthread_mutex_init(&SessionListMutex, NULL); /* * Start up the housekeeping thread */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&SessThread, &attr, (void *(*)(void *)) housekeeping_loop, NULL); /* * If this is an HTTPS server, fire up SSL */ #ifdef HAVE_OPENSSL if (is_https) { init_ssl(); } #endif drop_root(UID); /* Become a worker thread. More worker threads will be spawned as they are needed. */ worker_entry(); ShutDownLibCitadel(); return 0; }
int main() { icalarray *timezones; icaltimezone *zone, *utc_zone; char *zone_location; size_t i; int ret = 0; unsigned int total_failed = 0; unsigned int total_okay = 0; unsigned int percent_failed = 0; int verbose = 0; int day; time_t start_time; struct tm start_tm; time_t curr_time; struct tm curr_tm; struct icaltimetype curr_tt; int failed = 0; int curr_failed; int zonedef_printed = 0; #if !defined(HAVE_SETENV) static char new_tz[256]; #endif set_zone_directory("../../zoneinfo"); icaltimezone_set_tzid_prefix("/softwarestudio.org/"); timezones = icaltimezone_get_builtin_timezones(); utc_zone = icaltimezone_get_utc_timezone(); /* for all known time zones... */ for (i = 0; i < timezones->num_elements; i++) { zone = (icaltimezone *)icalarray_element_at(timezones, i); zone_location = (char *)icaltimezone_get_location(zone); if (!zone_location) continue; /* * select this location for glibc: needs support for TZ=<location> * which is not POSIX */ #if defined(HAVE_SETENV) setenv("TZ", zone_location, 1); #else new_tz[0] = '\0'; strncat(new_tz, "TZ=", 255); strncat(new_tz, zone_location, 255 - strlen(new_tz)); putenv(new_tz); #endif tzset(); /* * determine current local time and date: always use midday in * the current zone and first day of first month in the year */ start_time = time(NULL); localtime_r(&start_time, &start_tm); start_tm.tm_hour = 12; start_tm.tm_min = 0; start_tm.tm_sec = 0; start_tm.tm_mday = 1; start_tm.tm_mon = 0; start_time = mktime(&start_tm); /* check time conversion for the next 365 days */ for (day = 0, curr_time = start_time; day < 365; day++, curr_time += 24 * 60 * 60) { /* determine date/time with glibc */ localtime_r(&curr_time, &curr_tm); /* determine date/time with libical */ curr_tt = icaltime_from_timet_with_zone(curr_time, 0, utc_zone); curr_tt.zone = utc_zone; /* workaround: icaltime_from_timet_with_zone() should do this, but doesn't! */ curr_tt = icaltime_convert_to_zone(curr_tt, zone); /* compare... */ curr_failed = curr_tm.tm_year + 1900 != curr_tt.year || curr_tm.tm_mon + 1 != curr_tt.month || curr_tm.tm_mday != curr_tt.day || curr_tm.tm_hour != curr_tt.hour || curr_tm.tm_min != curr_tt.minute || curr_tm.tm_sec != curr_tt.second; /* only print first failed day and first day which is okay again */ if (verbose || curr_failed != failed) { struct tm utc_tm; if (!gmtime_r(&curr_time, &utc_tm)) memset(&utc_tm, 0, sizeof(utc_tm)); printf( "%s: day %03d: %s: %04d-%02d-%02d %02d:%02d:%02d UTC = " "libc %04d-%02d-%02d %02d:%02d:%02d dst %d", zone_location, day, verbose ? (curr_failed ? "failed" : "okay") : (curr_failed ? "first failed" : "okay again"), utc_tm.tm_year + 1900, utc_tm.tm_mon + 1, utc_tm.tm_mday, utc_tm.tm_hour, utc_tm.tm_min, utc_tm.tm_sec, curr_tm.tm_year + 1900, curr_tm.tm_mon + 1, curr_tm.tm_mday, curr_tm.tm_hour, curr_tm.tm_min, curr_tm.tm_sec, curr_tm.tm_isdst); if (curr_failed) { printf(" != libical %04d-%02d-%02d %02d:%02d:%02d dst %d", curr_tt.year, curr_tt.month, curr_tt.day, curr_tt.hour, curr_tt.minute, curr_tt.second, curr_tt.is_daylight); ret = 1; } printf("\n"); failed = curr_failed; if (!zonedef_printed) { icalcomponent *comp = icaltimezone_get_component(zone); if (comp) { printf("%s\n", icalcomponent_as_ical_string(comp)); } zonedef_printed = 1; } } if (curr_failed) { total_failed++; } else { total_okay++; } } } if (total_failed || total_okay) { percent_failed = total_failed * 100 / (total_failed + total_okay); printf(" *** Summary: %lu zones tested, %u days failed, %u okay => %u%% failed ***\n", (unsigned long)timezones->num_elements, total_failed, total_okay, percent_failed); if (!icaltzutil_get_exact_vtimezones_support()) { if (!percent_failed) { ret = 0; printf(" *** Expect some small error rate with inter-operable vtimezones *** \n"); } } } icaltimezone_free_builtin_timezones(); return ret; }