#include <string.h>
#include <ctype.h>
#include <errno.h>
-#include <netdb.h>
#if (HAVE_WCTYPE_H && HAVE_WCHAR_H)
# include <wchar.h>
#include "intl.h"
#include "utils.h"
+#include "socket.h"
#include "statusbar.h"
#include "logwindow.h"
gchar *get_domain_name(void)
{
static gchar *domain_name = NULL;
- struct hostent *myfqdn = NULL;
if (!domain_name) {
- gchar buf[BUFFSIZE] = "";
+ gchar buf[128] = "";
+ struct hostent *hp;
if (gethostname(buf, sizeof(buf)) < 0) {
perror("gethostname");
- strcpy(buf, "unknown");
- } else {
- myfqdn = gethostbyname(buf);
- if (myfqdn != NULL) {
- memset(buf, '\0', strlen(buf));
- strcpy(buf, myfqdn->h_name);
- } else {
- perror("gethostbyname");
- strcpy(buf, "unknown");
- }
- }
+ domain_name = "unknown";
+ } else {
+ buf[sizeof(buf) - 1] = '\0';
+ if ((hp = my_gethostbyname(buf)) == NULL) {
+ perror("gethostbyname");
+ domain_name = g_strdup(buf);
+ } else {
+ domain_name = g_strdup(hp->h_name);
+ }
+ }
- domain_name = g_strdup(buf);
+ debug_print("domain name = %s\n", domain_name);
}
return domain_name;
return 0;
}
+gint make_dir(const gchar *dir)
+{
+ if (mkdir(dir, S_IRWXU) < 0) {
+ FILE_OP_ERROR(dir, "mkdir");
+ return -1;
+ }
+ if (chmod(dir, S_IRWXU) < 0)
+ FILE_OP_ERROR(dir, "chmod");
+
+ return 0;
+}
+
gint make_dir_hier(const gchar *dir)
{
gchar *parent_dir;
parent_dir = g_strndup(dir, p - dir);
if (*parent_dir != '\0') {
if (!is_dir_exist(parent_dir)) {
- if (mkdir(parent_dir, S_IRWXU) < 0) {
- FILE_OP_ERROR(parent_dir, "mkdir");
+ if (make_dir(parent_dir) < 0) {
g_free(parent_dir);
return -1;
}
- if (chmod(parent_dir, S_IRWXU) < 0)
- FILE_OP_ERROR(parent_dir, "chmod");
}
}
g_free(parent_dir);
}
+
if (!is_dir_exist(dir)) {
- if (mkdir(dir, S_IRWXU) < 0) {
- FILE_OP_ERROR(dir, "mkdir");
+ if (make_dir(dir) < 0)
return -1;
- }
- if (chmod(dir, S_IRWXU) < 0)
- FILE_OP_ERROR(dir, "chmod");
}
return 0;
while ((d = readdir(dp)) != NULL) {
fileno = to_number(d->d_name);
if (fileno >= 0 && first <= fileno && fileno <= last) {
+ if (is_dir_exist(d->d_name))
+ continue;
if (unlink(d->d_name) < 0)
FILE_OP_ERROR(d->d_name, "unlink");
}
return remove_numbered_files(dir, 0, UINT_MAX);
}
+gint remove_expired_files(const gchar *dir, guint hours)
+{
+ DIR *dp;
+ struct dirent *d;
+ struct stat s;
+ gchar *prev_dir;
+ gint fileno;
+ time_t mtime, now, expire_time;
+
+ prev_dir = g_get_current_dir();
+
+ if (chdir(dir) < 0) {
+ FILE_OP_ERROR(dir, "chdir");
+ return -1;
+ }
+
+ if ((dp = opendir(".")) == NULL) {
+ FILE_OP_ERROR(dir, "opendir");
+ return -1;
+ }
+
+ now = time(NULL);
+ expire_time = hours * 60 * 60;
+
+ while ((d = readdir(dp)) != NULL) {
+ fileno = to_number(d->d_name);
+ if (fileno >= 0) {
+ if (stat(d->d_name, &s) < 0) {
+ FILE_OP_ERROR(d->d_name, "stat");
+ continue;
+ }
+ if (S_ISDIR(s.st_mode))
+ continue;
+ mtime = MAX(s.st_mtime, s.st_atime);
+ if (now - mtime > expire_time) {
+ if (unlink(d->d_name) < 0)
+ FILE_OP_ERROR(d->d_name, "unlink");
+ }
+ }
+ }
+
+ closedir(dp);
+
+ if (chdir(prev_dir) < 0) {
+ FILE_OP_ERROR(prev_dir, "chdir");
+ g_free(prev_dir);
+ return -1;
+ }
+
+ g_free(prev_dir);
+
+ return 0;
+}
+
gint remove_dir_recursive(const gchar *dir)
{
struct stat s;
return 0;
}
+/* convert line endings into CRLF. If the last line doesn't end with
+ * linebreak, add it.
+ */
+gint canonicalize_file(const gchar *src, const gchar *dest)
+{
+ FILE *src_fp, *dest_fp;
+ gchar buf[BUFFSIZE];
+ gint len;
+ gboolean err = FALSE;
+ gboolean last_linebreak = FALSE;
+
+ if ((src_fp = fopen(src, "rb")) == NULL) {
+ FILE_OP_ERROR(src, "fopen");
+ return -1;
+ }
+
+ if ((dest_fp = fopen(dest, "wb")) == NULL) {
+ FILE_OP_ERROR(dest, "fopen");
+ fclose(src_fp);
+ return -1;
+ }
+
+ if (change_file_mode_rw(dest_fp, dest) < 0) {
+ FILE_OP_ERROR(dest, "chmod");
+ g_warning("can't change file mode\n");
+ }
+
+ while (fgets(buf, sizeof(buf), src_fp) != NULL) {
+ gint r = 0;
+
+ len = strlen(buf);
+ if (len == 0) break;
+ last_linebreak = FALSE;
+
+ if (buf[len - 1] != '\n') {
+ last_linebreak = TRUE;
+ r = fputs(buf, dest_fp);
+ } else if (len > 1 && buf[len - 1] == '\n' && buf[len - 2] == '\r') {
+ r = fputs(buf, dest_fp);
+ } else {
+ if (len > 1) {
+ r = fwrite(buf, len - 1, 1, dest_fp);
+ if (r != 1)
+ r = EOF;
+ }
+ if (r != EOF)
+ r = fputs("\r\n", dest_fp);
+ }
+
+ if (r == EOF) {
+ g_warning("writing to %s failed.\n", dest);
+ fclose(dest_fp);
+ fclose(src_fp);
+ unlink(dest);
+ return -1;
+ }
+ }
+
+ if (last_linebreak == TRUE) {
+ if (fputs("\r\n", dest_fp) == EOF)
+ err = TRUE;
+ }
+
+ if (ferror(src_fp)) {
+ FILE_OP_ERROR(src, "fread");
+ err = TRUE;
+ }
+ fclose(src_fp);
+ if (fclose(dest_fp) == EOF) {
+ FILE_OP_ERROR(dest, "fclose");
+ err = TRUE;
+ }
+
+ if (err) {
+ unlink(dest);
+ return -1;
+ }
+
+ return 0;
+}
+
+gint canonicalize_file_replace(const gchar *file)
+{
+ gchar *tmp_file;
+
+ tmp_file = get_tmp_file();
+
+ if (canonicalize_file(file, tmp_file) < 0)
+ return -1;
+
+ unlink(file);
+ if (rename(tmp_file, file) < 0) {
+ FILE_OP_ERROR(file, "rename");
+ unlink(tmp_file);
+ return -1;
+ }
+
+ return 0;
+}
+
gint change_file_mode_rw(FILE *fp, const gchar *file)
{
#if HAVE_FCHMOD
fputs(buf, stdout);
}
+#define TIME_LEN 11
+
void log_print(const gchar *format, ...)
{
va_list args;
- gchar buf[BUFFSIZE];
- gchar *logbuf;
- gchar timestr[6];
+ gchar buf[BUFFSIZE + TIME_LEN];
time_t t;
+ time(&t);
+ strftime(buf, TIME_LEN + 1, "[%H:%M:%S] ", localtime(&t));
+
va_start(args, format);
- g_vsnprintf(buf, sizeof(buf), format, args);
+ g_vsnprintf(buf + TIME_LEN, BUFFSIZE, format, args);
va_end(args);
-
- time(&t);
- strftime(timestr, 6, "%H:%M", localtime(&t));
- logbuf = g_strdup_printf("[%s] %s", timestr, buf);
- if (debug_mode) fputs(logbuf, stdout);
- log_window_append(logbuf, LOG_NORMAL);
+ if (debug_mode) fputs(buf, stdout);
+ log_window_append(buf, LOG_NORMAL);
if (log_fp) {
- fputs(logbuf, log_fp);
+ fputs(buf, log_fp);
fflush(log_fp);
}
if (log_verbosity_count)
- statusbar_puts_all(buf);
- g_free(logbuf);
+ statusbar_puts_all(buf + TIME_LEN);
}
void log_message(const gchar *format, ...)
{
va_list args;
- gchar buf[BUFFSIZE];
+ gchar buf[BUFFSIZE + TIME_LEN];
+ time_t t;
+
+ time(&t);
+ strftime(buf, TIME_LEN + 1, "[%H:%M:%S] ", localtime(&t));
va_start(args, format);
- g_vsnprintf(buf, sizeof(buf), format, args);
+ g_vsnprintf(buf + TIME_LEN, BUFFSIZE, format, args);
va_end(args);
- if (debug_mode) g_message("%s", buf);
- log_window_append(buf, LOG_MSG);
+ if (debug_mode) g_message("%s", buf + TIME_LEN);
+ log_window_append(buf + TIME_LEN, LOG_MSG);
if (log_fp) {
- fputs("message: ", log_fp);
- fputs(buf, log_fp);
+ fwrite(buf, TIME_LEN, 1, log_fp);
+ fputs("* message: ", log_fp);
+ fputs(buf + TIME_LEN, log_fp);
fflush(log_fp);
}
- statusbar_puts_all(buf);
+ statusbar_puts_all(buf + TIME_LEN);
}
void log_warning(const gchar *format, ...)
{
va_list args;
- gchar buf[BUFFSIZE];
+ gchar buf[BUFFSIZE + TIME_LEN];
+ time_t t;
+
+ time(&t);
+ strftime(buf, TIME_LEN + 1, "[%H:%M:%S] ", localtime(&t));
va_start(args, format);
- g_vsnprintf(buf, sizeof(buf), format, args);
+ g_vsnprintf(buf + TIME_LEN, BUFFSIZE, format, args);
va_end(args);
g_warning("%s", buf);
- log_window_append(buf, LOG_WARN);
+ log_window_append(buf + TIME_LEN, LOG_WARN);
if (log_fp) {
- fputs("*** warning: ", log_fp);
- fputs(buf, log_fp);
+ fwrite(buf, TIME_LEN, 1, log_fp);
+ fputs("** warning: ", log_fp);
+ fputs(buf + TIME_LEN, log_fp);
fflush(log_fp);
}
}
void log_error(const gchar *format, ...)
{
va_list args;
- gchar buf[BUFFSIZE];
+ gchar buf[BUFFSIZE + TIME_LEN];
+ time_t t;
+
+ time(&t);
+ strftime(buf, TIME_LEN + 1, "[%H:%M:%S] ", localtime(&t));
va_start(args, format);
- g_vsnprintf(buf, sizeof(buf), format, args);
+ g_vsnprintf(buf + TIME_LEN, BUFFSIZE, format, args);
va_end(args);
g_warning("%s", buf);
- log_window_append(buf, LOG_ERROR);
+ log_window_append(buf + TIME_LEN, LOG_ERROR);
if (log_fp) {
+ fwrite(buf, TIME_LEN, 1, log_fp);
fputs("*** error: ", log_fp);
- fputs(buf, log_fp);
+ fputs(buf + TIME_LEN, log_fp);
fflush(log_fp);
}
}