static int download_staff_file(ConfigEntry *ce) { int ret = 0; struct stat sb; char *file, *filename; if (Download.in_progress) return 0; Download.is_url = 1; ircstrdup(Download.url, ce->ce_vardata); file = url_getfilename(ce->ce_vardata); filename = unreal_getfilename(file); /* TODO: handle NULL returns */ ircstrdup(Download.file, filename); MyFree(file); if (!loop.ircd_rehashing && !Download.once_completed) { char *error; if (config_verbose > 0) config_status("Downloading %s", Download.url); if (!(file = download_file(ce->ce_vardata, &error))) { config_error("%s:%i: test: error downloading '%s': %s", ce->ce_fileptr->cf_filename, ce->ce_varlinenum, ce->ce_vardata, error); return -1; } Download.once_completed = 1; ircstrdup(Download.path, file); read_motd(Download.path, &staff); MyFree(file); return 0; } file = Download.path ? Download.path : Download.file; if ((ret = stat(file, &sb)) && errno != ENOENT) { /* I know, stat shouldn't fail... */ config_error("%s:%i: could not get the creation time of %s: stat() returned %d: %s", ce->ce_fileptr->cf_filename, ce->ce_varlinenum, Download.file, ret, strerror(errno)); return -1; } if (config_verbose > 0) config_status("Downloading %s", Download.url); Download.in_progress = 1; download_file_async(Download.url, sb.st_ctime, download_staff_file_complete, NULL); return 0; }
static void remove_staff_file() { if (Download.path) { if (remove(Download.path) == -1) { if (config_verbose > 0) config_status("Cannot remove file %s: %s", Download.path, strerror(errno)); } MyFree(Download.path); Download.path = NULL; } }
/* irc logs.. */ void ircd_log(int flags, char *format, ...) { static int last_log_file_warning = 0; static char recursion_trap=0; va_list ap; ConfigItem_log *logs; char buf[2048], timebuf[128]; struct stat fstats; int written = 0, write_failure = 0; int n; /* Trap infinite recursions to avoid crash if log file is unavailable, * this will also avoid calling ircd_log from anything else called */ if (recursion_trap == 1) return; recursion_trap = 1; va_start(ap, format); ircvsnprintf(buf, sizeof(buf), format, ap); va_end(ap); snprintf(timebuf, sizeof(timebuf), "[%s] - ", myctime(TStime())); RunHook3(HOOKTYPE_LOG, flags, timebuf, buf); strlcat(buf, "\n", sizeof(buf)); if (!loop.ircd_forked && (flags & LOG_ERROR)) fprintf(stderr, "%s", buf); for (logs = conf_log; logs; logs = (ConfigItem_log *) logs->next) { #ifdef HAVE_SYSLOG if (!stricmp(logs->file, "syslog") && logs->flags & flags) { syslog(LOG_INFO, "%s", buf); written++; continue; } #endif if (logs->flags & flags) { if (stat(logs->file, &fstats) != -1 && logs->maxsize && fstats.st_size >= logs->maxsize) { char oldlog[512]; if (logs->logfd != -1) { write(logs->logfd, "Max file size reached, starting new log file\n", 45); fd_close(logs->logfd); } /* Rename log file to xxxxxx.old */ snprintf(oldlog, sizeof(oldlog), "%s.old", logs->file); rename(logs->file, oldlog); logs->logfd = fd_fileopen(logs->file, O_CREAT|O_WRONLY|O_TRUNC); if (logs->logfd == -1) continue; } else if (logs->logfd == -1) { #ifndef _WIN32 logs->logfd = fd_fileopen(logs->file, O_CREAT|O_APPEND|O_WRONLY); #else logs->logfd = fd_fileopen(logs->file, O_CREAT|O_APPEND|O_WRONLY); #endif if (logs->logfd == -1) { if (!loop.ircd_booted) { config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO)); } else { if (last_log_file_warning + 300 < TStime()) { config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO)); last_log_file_warning = TStime(); } } write_failure = 1; continue; } } /* this shouldn't happen, but lets not waste unnecessary syscalls... */ if (logs->logfd == -1) continue; write(logs->logfd, timebuf, strlen(timebuf)); n = write(logs->logfd, buf, strlen(buf)); if (n == strlen(buf)) { written++; } else { if (!loop.ircd_booted) { config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO)); } else { if (last_log_file_warning + 300 < TStime()) { config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO)); last_log_file_warning = TStime(); } } write_failure = 1; } #ifndef _WIN32 fsync(logs->logfd); #endif } } recursion_trap = 0; }
/* irc logs.. */ void ircd_log(int flags, char *format, ...) { static int last_log_file_warning = 0; va_list ap; ConfigItem_log *logs; char buf[2048], timebuf[128]; struct stat fstats; int written = 0, write_failure = 0; va_start(ap, format); ircvsnprintf(buf, sizeof(buf), format, ap); va_end(ap); snprintf(timebuf, sizeof(timebuf), "[%s] - ", myctime(TStime())); RunHook3(HOOKTYPE_LOG, flags, timebuf, buf); strlcat(buf, "\n", sizeof(buf)); for (logs = conf_log; logs; logs = (ConfigItem_log *) logs->next) { #ifdef HAVE_SYSLOG if (!stricmp(logs->file, "syslog") && logs->flags & flags) { syslog(LOG_INFO, "%s", buf); written++; continue; } #endif if (logs->flags & flags) { if (stat(logs->file, &fstats) != -1 && logs->maxsize && fstats.st_size >= logs->maxsize) { if (logs->logfd != -1) fd_close(logs->logfd); logs->logfd = fd_fileopen(logs->file, O_CREAT|O_WRONLY|O_TRUNC); if (logs->logfd == -1) continue; if (write(logs->logfd, "Max file size reached, starting new log file\n", 45) < 0) { write_failure = 1; continue; } } else if (logs->logfd == -1) { logs->logfd = fd_fileopen(logs->file, O_CREAT|O_APPEND|O_WRONLY); if (logs->logfd == -1) { if (!loop.ircd_booted) { config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO)); } else { if (last_log_file_warning + 300 < TStime()) { config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO)); last_log_file_warning = TStime(); } } write_failure = 1; continue; } } /* this shouldn't happen, but lets not waste unnecessary syscalls... */ if (logs->logfd == -1) continue; if (write(logs->logfd, timebuf, strlen(timebuf)) < 0) { if (!loop.ircd_booted) { config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO)); } else { if (last_log_file_warning + 300 < TStime()) { config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO)); last_log_file_warning = TStime(); } } write_failure = 1; } if (write(logs->logfd, buf, strlen(buf)) == strlen(buf)) { written++; } else { if (!loop.ircd_booted) { config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO)); } else { if (last_log_file_warning + 300 < TStime()) { config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO)); last_log_file_warning = TStime(); } } write_failure = 1; } fsync(logs->logfd); } } /* If nothing got written at all AND we had a write failure AND we are booting, then exit. * Note that we can't just fail when nothing got written, as we might have been called for * 'tkl' for example, which might not be in our log block. */ if (!written && write_failure && !loop.ircd_booted) { config_status("ERROR: Unable to write to any log file. Please check your log { } blocks and file permissions!"); exit(9); } }