Mercurial > pidgin
view src/util.c @ 2906:538c58b43eff
[gaim-migrate @ 2919]
save
save me from this
wandered around the town
all the thousand things
i might miss
and you
think we'll suffer much
think we'll close our eyes
just to see the light
pass us by
with tomorrow coming
hope that i don't let you
down again
said i'm so glad to be here
does it mean a thing
if only i could breathe what you breathe
if only i could see what you see
sit
we'll take our time
watching the flowers grow
all the friends we've known
say goodbye
and you
did you suffer much
did you close your eyes
just to see the night
rush on by
gathered all around you
hope that we don't let you
down again
i said i'm so glad to be here
does it mean a thing
if only i could breathe what you breathe
if only i could see what you see
i said i'm so glad to be here
does it mean a thing
if only i could breathe what you breathe
if only i could see what you see
if only i could just believe a thing
--Moist, "Breathe" (as transcribed by http://www.veddma.com/veddma/moist.htm)
Patches from:
Ari Pollak
Ben Miller
Mark Doliner
Sean Egan
Vincas Ciziunas
Thanks everyone.
Somewhere in the middle of all of this it started to get really tedious and annoying. I think it's getting close to the point where I quit.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Fri, 21 Dec 2001 10:23:04 +0000 |
parents | cd23279122ed |
children | b68c648618a3 |
line wrap: on
line source
/* * gaim * * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <unistd.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <sys/wait.h> #include <ctype.h> #include <math.h> #include "gaim.h" #include "prpl.h" char *full_date() { char *date; time_t tme; time(&tme); date = ctime(&tme); date[strlen(date) - 1] = '\0'; return date; } gint badchar(char c) { switch (c) { case ' ': case ',': case '(': case ')': case '\0': case '\n': case '<': case '>': case '"': return 1; default: return 0; } } gchar *sec_to_text(guint sec) { int daze, hrs, min; char *ret = g_malloc(256); daze = sec / (60 * 60 * 24); hrs = (sec % (60 * 60 * 24)) / (60 * 60); min = (sec % (60 * 60)) / 60; sec = min % 60; if (daze) { if (hrs || min) { if (hrs) { if (min) { g_snprintf(ret, 256, "%d day%s, %d hour%s, %d minute%s.", daze, daze == 1 ? "" : "s", hrs, hrs == 1 ? "" : "s", min, min == 1 ? "" : "s"); } else { g_snprintf(ret, 256, "%d day%s, %d hour%s.", daze, daze == 1 ? "" : "s", hrs, hrs == 1 ? "" : "s"); } } else { g_snprintf(ret, 256, "%d day%s, %d minute%s.", daze, daze == 1 ? "" : "s", min, min == 1 ? "" : "s"); } } else g_snprintf(ret, 256, "%d day%s.", daze, daze == 1 ? "" : "s"); } else { if (hrs) { if (min) { g_snprintf(ret, 256, "%d hour%s, %d minute%s.", hrs, hrs == 1 ? "" : "s", min, min == 1 ? "" : "s"); } else { g_snprintf(ret, 256, "%d hour%s.", hrs, hrs == 1 ? "" : "s"); } } else { g_snprintf(ret, 256, "%d minute%s.", min, min == 1 ? "" : "s"); } } return ret; } gint linkify_text(char *text) { char *c, *t; char *cpy = g_malloc(strlen(text) * 3 + 1); char url_buf[BUF_LEN * 4]; int cnt = 0; /* Assumes you have a buffer able to cary at least BUF_LEN * 2 bytes */ strncpy(cpy, text, strlen(text)); cpy[strlen(text)] = 0; c = cpy; while (*c) { if (!g_strncasecmp(c, "<A", 2)) { while (1) { if (!g_strncasecmp(c, "/A>", 3)) { break; } text[cnt++] = *c; c++; if (!(*c)) break; } } else if ((!g_strncasecmp(c, "http://", 7) || (!g_strncasecmp(c, "https://", 8)))) { t = c; while (1) { if (badchar(*t)) { if (*(t) == ',' && (*(t + 1) != ' ')) { t++; continue; } if (*(t - 1) == '.') t--; strncpy(url_buf, c, t - c); url_buf[t - c] = 0; cnt += g_snprintf(&text[cnt], 1024, "<A HREF=\"%s\">%s</A>", url_buf, url_buf); c = t; break; } if (!t) break; t++; } } else if (!g_strncasecmp(c, "www.", 4)) { if (g_strncasecmp(c, "www..", 5)) { t = c; while (1) { if (badchar(*t)) { if (t - c == 4) { break; } if (*(t) == ',' && (*(t + 1) != ' ')) { t++; continue; } if (*(t - 1) == '.') t--; strncpy(url_buf, c, t - c); url_buf[t - c] = 0; cnt += g_snprintf(&text[cnt], 1024, "<A HREF=\"http://%s\">%s</A>", url_buf, url_buf); c = t; break; } if (!t) break; t++; } } } else if (!g_strncasecmp(c, "ftp://", 6)) { t = c; while (1) { if (badchar(*t)) { if (*(t - 1) == '.') t--; strncpy(url_buf, c, t - c); url_buf[t - c] = 0; cnt += g_snprintf(&text[cnt], 1024, "<A HREF=\"%s\">%s</A>", url_buf, url_buf); c = t; break; } if (!t) break; t++; } } else if (!g_strncasecmp(c, "ftp.", 4)) { if (g_strncasecmp(c, "ftp..", 5)) { t = c; while (1) { if (badchar(*t)) { if (t - c == 4) { break; } if (*(t - 1) == '.') t--; strncpy(url_buf, c, t - c); url_buf[t - c] = 0; cnt += g_snprintf(&text[cnt], 1024, "<A HREF=\"ftp://%s\">%s</A>", url_buf, url_buf); c = t; break; } if (!t) break; t++; } } } else if (!g_strncasecmp(c, "mailto:", 7)) { t = c; while (1) { if (badchar(*t)) { if (*(t - 1) == '.') t--; strncpy(url_buf, c, t - c); url_buf[t - c] = 0; cnt += g_snprintf(&text[cnt], 1024, "<A HREF=\"%s\">%s</A>", url_buf, url_buf); c = t; break; } if (!t) break; t++; } } else if (c != cpy && !g_strncasecmp(c, "@", 1)) { char *tmp; int flag; int len = 0; char illegal_chars[] = "!@#$%^&*()[]{}/\\<>\":;\0"; url_buf[0] = 0; if (*(c - 1) == ' ' || *(c + 1) == ' ' || rindex(illegal_chars, *(c + 1)) || *(c + 1) == 13 || *(c + 1) == 10) flag = 0; else flag = 1; t = c; while (flag) { if (badchar(*t)) { cnt -= (len - 1); break; } else { len++; tmp = g_malloc(len + 1); tmp[len] = 0; tmp[0] = *t; strncpy(tmp + 1, url_buf, len - 1); strcpy(url_buf, tmp); url_buf[len] = 0; g_free(tmp); t--; if (t < cpy) { cnt = 0; break; } } } t = c + 1; while (flag) { if (badchar(*t)) { if (*(t - 1) == '.') t--; cnt += g_snprintf(&text[cnt], 1024, "<A HREF=\"mailto:%s\">%s</A>", url_buf, url_buf); text[cnt] = 0; c = t; break; } else { strncat(url_buf, t, 1); len++; url_buf[len] = 0; } t++; } } if (*c == 0) break; text[cnt++] = *c; c++; } text[cnt] = 0; g_free(cpy); return cnt; } FILE *open_gaim_log_file(char *name, int *flag) { char *buf; char *buf2; char log_all_file[256]; struct stat st; FILE *fd; int res; gchar *gaim_dir; buf = g_malloc(BUF_LONG); buf2 = g_malloc(BUF_LONG); gaim_dir = gaim_user_dir(); /* Dont log yourself */ strncpy(log_all_file, gaim_dir, 256); stat(log_all_file, &st); if (!S_ISDIR(st.st_mode)) unlink(log_all_file); fd = fopen(log_all_file, "r"); if (!fd) { res = mkdir(log_all_file, S_IRUSR | S_IWUSR | S_IXUSR); if (res < 0) { g_snprintf(buf, BUF_LONG, "Unable to make directory %s for logging", log_all_file); do_error_dialog(buf, "Error!"); g_free(buf); g_free(buf2); g_free(gaim_dir); return NULL; } } else fclose(fd); g_snprintf(log_all_file, 256, "%s/logs", gaim_dir); if (stat(log_all_file, &st) < 0) *flag = 1; if (!S_ISDIR(st.st_mode)) unlink(log_all_file); fd = fopen(log_all_file, "r"); if (!fd) { res = mkdir(log_all_file, S_IRUSR | S_IWUSR | S_IXUSR); if (res < 0) { g_snprintf(buf, BUF_LONG, "Unable to make directory %s for logging", log_all_file); do_error_dialog(buf, "Error!"); g_free(buf); g_free(buf2); g_free(gaim_dir); return NULL; } } else fclose(fd); g_snprintf(log_all_file, 256, "%s/logs/%s", gaim_dir, name); if (stat(log_all_file, &st) < 0) *flag = 1; debug_printf("Logging to: \"%s\"\n", log_all_file); fd = fopen(log_all_file, "a"); g_free(buf); g_free(buf2); g_free(gaim_dir); return fd; } FILE *open_log_file(char *name) { struct stat st; char realname[256]; struct log_conversation *l; FILE *fd; int flag = 0; if (!(logging_options & OPT_LOG_ALL)) { l = find_log_info(name); if (!l) return NULL; if (stat(l->filename, &st) < 0) flag = 1; fd = fopen(l->filename, "a"); if (flag) { /* is a new file */ if (logging_options & OPT_LOG_STRIP_HTML) { fprintf(fd, "IM Sessions with %s\n", name); } else { fprintf(fd, "<HTML><HEAD><TITLE>"); fprintf(fd, "IM Sessions with %s", name); fprintf(fd, "</TITLE></HEAD><BODY BGCOLOR=\"ffffff\">\n"); } } return fd; } g_snprintf(realname, sizeof(realname), "%s.log", normalize(name)); fd = open_gaim_log_file(realname, &flag); if (fd && flag) { /* is a new file */ if (logging_options & OPT_LOG_STRIP_HTML) { fprintf(fd, "IM Sessions with %s\n", name); } else { fprintf(fd, "<HTML><HEAD><TITLE>"); fprintf(fd, "IM Sessions with %s", name); fprintf(fd, "</TITLE></HEAD><BODY BGCOLOR=\"ffffff\">\n"); } } return fd; } FILE *open_system_log_file(char *name) { int x; if (name) return open_log_file(name); else return open_gaim_log_file("system", &x); } char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789+/"; char *tobase64(const char *text) { char *out = NULL; const char *c; unsigned int tmp = 0; int len = 0, n = 0; c = text; while (*c) { tmp = tmp << 8; tmp += *c; n++; if (n == 3) { out = g_realloc(out, len + 4); out[len] = alphabet[(tmp >> 18) & 0x3f]; out[len + 1] = alphabet[(tmp >> 12) & 0x3f]; out[len + 2] = alphabet[(tmp >> 6) & 0x3f]; out[len + 3] = alphabet[tmp & 0x3f]; len += 4; tmp = 0; n = 0; } c++; } switch (n) { case 2: tmp <<= 8; out = g_realloc(out, len + 5); out[len] = alphabet[(tmp >> 18) & 0x3f]; out[len + 1] = alphabet[(tmp >> 12) & 0x3f]; out[len + 2] = alphabet[(tmp >> 6) & 0x3f]; out[len + 3] = '='; out[len + 4] = 0; break; case 1: tmp <<= 16; out = g_realloc(out, len + 5); out[len] = alphabet[(tmp >> 18) & 0x3f]; out[len + 1] = alphabet[(tmp >> 12) & 0x3f]; out[len + 2] = '='; out[len + 3] = '='; out[len + 4] = 0; break; case 0: out = g_realloc(out, len + 1); out[len] = 0; break; } return out; } void frombase64(const char *text, char **data, int *size) { char *out = NULL; char tmp = 0; const char *c; gint32 tmp2 = 0; int len = 0, n = 0; if (!text || !data) return; c = text; while (*c) { if (*c >= 'A' && *c <= 'Z') { tmp = *c - 'A'; } else if (*c >= 'a' && *c <= 'z') { tmp = 26 + (*c - 'a'); } else if (*c >= '0' && *c <= 57) { tmp = 52 + (*c - '0'); } else if (*c == '+') { tmp = 62; } else if (*c == '/') { tmp = 63; } else if (*c == '=') { if (n == 3) { out = g_realloc(out, len + 2); out[len] = (char)(tmp2 >> 10) & 0xff; len++; out[len] = (char)(tmp2 >> 2) & 0xff; len++; } else if (n == 2) { out = g_realloc(out, len + 1); out[len] = (char)(tmp2 >> 4) & 0xff; len++; } break; } tmp2 = ((tmp2 << 6) | (tmp & 0xff)); n++; if (n == 4) { out = g_realloc(out, len + 3); out[len] = (char)((tmp2 >> 16) & 0xff); len++; out[len] = (char)((tmp2 >> 8) & 0xff); len++; out[len] = (char)(tmp2 & 0xff); len++; tmp2 = 0; n = 0; } c++; } out = g_realloc(out, len + 1); out[len] = 0; *data = out; if (size) *size = len; } char *normalize(const char *s) { static char buf[BUF_LEN]; char *t, *u; int x = 0; g_return_val_if_fail((s != NULL), NULL); u = t = g_strdup(s); strcpy(t, s); g_strdown(t); while (*t && (x < BUF_LEN - 1)) { if (*t != ' ') { buf[x] = *t; x++; } t++; } buf[x] = '\0'; g_free(u); return buf; } char *date() { static char date[80]; time_t tme; time(&tme); strftime(date, sizeof(date), "%H:%M:%S", localtime(&tme)); return date; } gboolean clean_pid(gpointer dummy) { int status; pid_t pid; pid = waitpid(-1, &status, WNOHANG); if (pid == 0) return TRUE; return FALSE; } struct aim_user *find_user(const char *name, int protocol) { char *who = g_strdup(normalize(name)); GSList *usr = aim_users; struct aim_user *u; while (usr) { u = (struct aim_user *)usr->data; if (!strcmp(normalize(u->username), who)) { if (protocol != -1) { if (u->protocol == protocol) { g_free(who); return u; } } else { g_free(who); return u; } } usr = usr->next; } g_free(who); return NULL; } /* Look for %n, %d, or %t in msg, and replace with the sender's name, date, or time */ char *away_subs(char *msg, char *name) { char *c; static char cpy[BUF_LONG]; int cnt = 0; time_t t = time(0); struct tm *tme = localtime(&t); char tmp[20]; cpy[0] = '\0'; c = msg; while (*c) { switch (*c) { case '%': if (*(c + 1)) { switch (*(c + 1)) { case 'n': /* append name */ strcpy(cpy + cnt, name); cnt += strlen(name); c++; break; case 'd': /* append date */ strftime(tmp, 20, "%m/%d/%Y", tme); strcpy(cpy + cnt, tmp); cnt += strlen(tmp); c++; break; case 't': /* append time */ strftime(tmp, 20, "%r", tme); strcpy(cpy + cnt, tmp); cnt += strlen(tmp); c++; break; default: cpy[cnt++] = *c; } } break; default: cpy[cnt++] = *c; } c++; } cpy[cnt] = '\0'; return (cpy); } char *stylize(gchar *text, int length) { gchar *buf; char *tmp = g_malloc(length); buf = g_malloc(length); g_snprintf(buf, length, "%s", text); if (font_options & OPT_FONT_BOLD) { g_snprintf(tmp, length, "<B>%s</B>", buf); strcpy(buf, tmp); } if (font_options & OPT_FONT_ITALIC) { g_snprintf(tmp, length, "<I>%s</I>", buf); strcpy(buf, tmp); } if (font_options & OPT_FONT_UNDERLINE) { g_snprintf(tmp, length, "<U>%s</U>", buf); strcpy(buf, tmp); } if (font_options & OPT_FONT_STRIKE) { g_snprintf(tmp, length, "<S>%s</S>", buf); strcpy(buf, tmp); } if (font_options & OPT_FONT_FACE) { g_snprintf(tmp, length, "<FONT FACE=\"%s\">%s</FONT>", fontface, buf); strcpy(buf, tmp); } if (font_options & OPT_FONT_SIZE) { g_snprintf(tmp, length, "<FONT SIZE=\"%d\">%s</FONT>", fontsize, buf); strcpy(buf, tmp); } if (font_options & OPT_FONT_FGCOL) { g_snprintf(tmp, length, "<FONT COLOR=\"#%02X%02X%02X\">%s</FONT>", fgcolor.red, fgcolor.green, fgcolor.blue, buf); strcpy(buf, tmp); } if (font_options & OPT_FONT_BGCOL) { g_snprintf(tmp, length, "<BODY BGCOLOR=\"#%02X%02X%02X\">%s</BODY>", bgcolor.red, bgcolor.green, bgcolor.blue, buf); strcpy(buf, tmp); } g_free(tmp); return buf; } void show_usage(int mode, char *name) { switch (mode) { case 0: /* full help text */ printf("Usage: %s [OPTION]...\n\n" " -a, --acct display account editor window\n" " -w, --away[=MESG] make away on signon (optional argument MESG specifies\n" " name of away message to use)\n" " -l, --login[=NAME] automatically login (optional argument NAME specifies\n" " account(s) to use)\n" " -u, --user=NAME use account NAME\n" " -f, --file=FILE use FILE as config\n" " -d, --debug print debugging messages to stdout\n" " -v, --version display version information window\n" " -h, --help display this help and exit\n", name); break; case 1: /* short message */ printf("Try `%s -h' for more information.\n", name); break; } } /* <name> is a comma-separated list of names, or NULL if NULL and there is at least one user defined in .gaimrc, try to login. if not NULL, parse <name> into separate strings, look up each one in .gaimrc and, if it's there, try to login. returns: 0 if successful -1 if no user was found that had a saved password */ int do_auto_login(char *name) { struct aim_user *u; char **names, **n; int retval = -1; if (name !=NULL) { /* list of names given */ names = g_strsplit(name, ",", 32); for (n = names; *n != NULL; n++) { u = find_user(*n, -1); if (u) { /* found a user */ if (u->options & OPT_USR_REM_PASS) { retval = 0; serv_login(u); } } } g_strfreev(names); } else { /* no name given, use default */ u = (struct aim_user *)aim_users->data; if (u->options & OPT_USR_REM_PASS) { retval = 0; serv_login(u); } } return retval; } GSList *message_split(char *message, int limit) { static GSList *ret = NULL; int lastgood = 0, curgood = 0, curpos = 0, len = strlen(message); gboolean intag = FALSE; if (ret) { GSList *tmp = ret; while (tmp) { g_free(tmp->data); tmp = g_slist_remove(tmp, tmp->data); } ret = NULL; } while (TRUE) { if (lastgood >= len) return ret; if (len - lastgood < limit) { ret = g_slist_append(ret, g_strdup(&message[lastgood])); return ret; } curgood = curpos = 0; intag = FALSE; while (curpos <= limit) { if (isspace(message[curpos + lastgood]) && !intag) curgood = curpos; if (message[curpos + lastgood] == '<') intag = TRUE; if (message[curpos + lastgood] == '>') intag = FALSE; curpos++; } if (curgood) { ret = g_slist_append(ret, g_strndup(&message[lastgood], curgood)); if (isspace(message[curgood + lastgood])) lastgood += curgood + 1; else lastgood += curgood; } else { /* whoops, guess we have to fudge it here */ ret = g_slist_append(ret, g_strndup(&message[lastgood], limit)); lastgood += limit; } } } /* returns a string of the form ~/.gaim, where ~ is replaced by the user's home * dir. this string should be freed after it's used. Note that there is no * trailing slash after .gaim. */ gchar *gaim_user_dir() { return g_strjoin(G_DIR_SEPARATOR_S, g_get_home_dir(), ".gaim", NULL); } /* * rcg10312000 This could be more robust, but it works for my current * goal: to remove those annoying <BR> tags. :) * dtf12162000 made the loop more readable. i am a neat freak. ;) */ void strncpy_nohtml(gchar *dest, const gchar *src, size_t destsize) { gchar *ptr; g_snprintf(dest, destsize, "%s", src); while ((ptr = strstr(dest, "<BR>")) != NULL) { /* replace <BR> with a newline. */ *ptr = '\n'; memmove(ptr + 1, ptr + 4, strlen(ptr + 4) + 1); } } void strncpy_withhtml(gchar *dest, const gchar *src, size_t destsize) { gchar *end = dest + destsize; while (dest < end) { if (*src == '\n' && dest < end - 5) { strcpy(dest, "<BR>"); src++; dest += 4; } else { *dest++ = *src; if (*src == '\0') return; else src++; } } } void away_on_login(char *mesg) { GSList *awy = away_messages; struct away_message *a, *message = NULL; if (!blist) { return; } if (mesg == NULL) { /* Use default message */ do_away_message(NULL, default_away); } else { /* Use argument */ while (awy) { a = (struct away_message *)awy->data; if (strcmp(a->name, mesg) == 0) { message = a; break; } awy = awy->next; } if (message == NULL) message = default_away; do_away_message(NULL, message); } return; } void system_log(enum log_event what, struct gaim_connection *gc, struct buddy *who, int why) { FILE *fd; char text[256], html[256]; if ((logging_options & why) != why) return; if (logging_options & OPT_LOG_INDIVIDUAL) { if (why & OPT_LOG_MY_SIGNON) fd = open_system_log_file(gc ? gc->username : NULL); else fd = open_system_log_file(who->name); } else fd = open_system_log_file(NULL); if (!fd) return; if (why & OPT_LOG_MY_SIGNON) { switch (what) { case log_signon: g_snprintf(text, sizeof(text), "+++ %s (%s) signed on @ %s", gc->username, gc->prpl->name(), full_date()); g_snprintf(html, sizeof(html), "<B>%s</B>", text); break; case log_signoff: g_snprintf(text, sizeof(text), "+++ %s (%s) signed off @ %s", gc->username, gc->prpl->name(), full_date()); g_snprintf(html, sizeof(html), "<I><FONT COLOR=GRAY>%s</FONT></I>", text); break; case log_away: g_snprintf(text, sizeof(text), "+++ %s (%s) changed away state @ %s", gc->username, gc->prpl->name(), full_date()); g_snprintf(html, sizeof(html), "<FONT COLOR=OLIVE>%s</FONT>", text); break; case log_back: g_snprintf(text, sizeof(text), "+++ %s (%s) came back @ %s", gc->username, gc->prpl->name(), full_date()); g_snprintf(html, sizeof(html), "%s", text); break; case log_idle: g_snprintf(text, sizeof(text), "+++ %s (%s) became idle @ %s", gc->username, gc->prpl->name(), full_date()); g_snprintf(html, sizeof(html), "<FONT COLOR=GRAY>%s</FONT>", text); break; case log_unidle: g_snprintf(text, sizeof(text), "+++ %s (%s) returned from idle @ %s", gc->username, gc->prpl->name(), full_date()); g_snprintf(html, sizeof(html), "%s", text); break; case log_quit: g_snprintf(text, sizeof(text), "+++ Program exit @ %s", full_date()); g_snprintf(html, sizeof(html), "<I><FONT COLOR=GRAY>%s</FONT></I>", text); break; } } else if (strcmp(who->name, who->show)) { switch (what) { case log_signon: g_snprintf(text, sizeof(text), "%s (%s) reported that %s (%s) signed on @ %s", gc->username, gc->prpl->name(), who->show, who->name, full_date()); g_snprintf(html, sizeof(html), "<B>%s</B>", text); break; case log_signoff: g_snprintf(text, sizeof(text), "%s (%s) reported that %s (%s) signed off @ %s", gc->username, gc->prpl->name(), who->show, who->name, full_date()); g_snprintf(html, sizeof(html), "<I><FONT COLOR=GRAY>%s</FONT></I>", text); break; case log_away: g_snprintf(text, sizeof(text), "%s (%s) reported that %s (%s) went away @ %s", gc->username, gc->prpl->name(), who->show, who->name, full_date()); g_snprintf(html, sizeof(html), "<FONT COLOR=OLIVE>%s</FONT>", text); break; case log_back: g_snprintf(text, sizeof(text), "%s (%s) reported that %s (%s) came back @ %s", gc->username, gc->prpl->name(), who->show, who->name, full_date()); g_snprintf(html, sizeof(html), "%s", text); break; case log_idle: g_snprintf(text, sizeof(text), "%s (%s) reported that %s (%s) became idle @ %s", gc->username, gc->prpl->name(), who->show, who->name, full_date()); g_snprintf(html, sizeof(html), "<FONT COLOR=GRAY>%s</FONT>", text); break; case log_unidle: g_snprintf(text, sizeof(text), "%s (%s) reported that %s (%s) returned from idle @ %s", gc->username, gc->prpl->name(), who->show, who->name, full_date()); g_snprintf(html, sizeof(html), "%s", text); break; default: fclose(fd); return; break; } } else { switch (what) { case log_signon: g_snprintf(text, sizeof(text), "%s (%s) reported that %s signed on @ %s", gc->username, gc->prpl->name(), who->name, full_date()); g_snprintf(html, sizeof(html), "<B>%s</B>", text); break; case log_signoff: g_snprintf(text, sizeof(text), "%s (%s) reported that %s signed off @ %s", gc->username, gc->prpl->name(), who->name, full_date()); g_snprintf(html, sizeof(html), "<I><FONT COLOR=GRAY>%s</FONT></I>", text); break; case log_away: g_snprintf(text, sizeof(text), "%s (%s) reported that %s went away @ %s", gc->username, gc->prpl->name(), who->name, full_date()); g_snprintf(html, sizeof(html), "<FONT COLOR=OLIVE>%s</FONT>", text); break; case log_back: g_snprintf(text, sizeof(text), "%s (%s) reported that %s came back @ %s", gc->username, gc->prpl->name(), who->name, full_date()); g_snprintf(html, sizeof(html), "%s", text); break; case log_idle: g_snprintf(text, sizeof(text), "%s (%s) reported that %s became idle @ %s", gc->username, gc->prpl->name(), who->name, full_date()); g_snprintf(html, sizeof(html), "<FONT COLOR=GRAY>%s</FONT>", text); break; case log_unidle: g_snprintf(text, sizeof(text), "%s (%s) reported that %s returned from idle @ %s", gc->username, gc->prpl->name(), who->name, full_date()); g_snprintf(html, sizeof(html), "%s", text); break; default: fclose(fd); return; break; } } if (logging_options & OPT_LOG_STRIP_HTML) { fprintf(fd, "---- %s ----\n", text); } else { if (logging_options & OPT_LOG_INDIVIDUAL) fprintf(fd, "<HR>%s<BR><HR><BR>\n", html); else fprintf(fd, "%s<BR>\n", html); } fclose(fd); } unsigned char *utf8_to_str(unsigned char *in) { int n = 0, i = 0; int inlen; unsigned char *result; if (!in) return NULL; inlen = strlen(in); result = g_malloc(inlen + 1); while (n <= inlen - 1) { long c = (long)in[n]; if (c < 0x80) result[i++] = (char)c; else { if ((c & 0xC0) == 0xC0) result[i++] = (char)(((c & 0x03) << 6) | (((unsigned char)in[++n]) & 0x3F)); else if ((c & 0xE0) == 0xE0) { if (n + 2 <= inlen) { result[i] = (char)(((c & 0xF) << 4) | (((unsigned char)in[++n]) & 0x3F)); result[i] = (char)(((unsigned char)result[i]) | (((unsigned char)in[++n]) & 0x3F)); i++; } else n += 2; } else if ((c & 0xF0) == 0xF0) n += 3; else if ((c & 0xF8) == 0xF8) n += 4; else if ((c & 0xFC) == 0xFC) n += 5; } n++; } result[i] = '\0'; return result; } char *str_to_utf8(unsigned char *in) { int n = 0, i = 0; int inlen; char *result = NULL; if (!in) return NULL; inlen = strlen(in); result = g_malloc(inlen * 2 + 1); while (n < inlen) { long c = (long)in[n]; if (c == 27) { n += 2; if (in[n] == 'x') n++; if (in[n] == '3') n++; n += 2; continue; } /* why are we removing newlines and carriage returns? if ((c == 0x0D) || (c == 0x0A)) { n++; continue; } */ if (c < 128) result[i++] = (char)c; else { result[i++] = (char)((c >> 6) | 192); result[i++] = (char)((c & 63) | 128); } n++; } result[i] = '\0'; return result; } void strip_linefeed(gchar *text) { int i, j; gchar *text2 = g_malloc(strlen(text) + 1); for (i = 0, j = 0; text[i]; i++) if (text[i] != '\r') text2[j++] = text[i]; text2[j] = '\0'; strcpy(text, text2); g_free(text2); } char *add_cr(char *text) { char *ret = NULL; int count = 0, i, j; if (text[0] == '\n') count++; for (i = 1; i < strlen(text); i++) if (text[i] == '\n' && text[i - 1] != '\r') count++; if (count == 0) return g_strdup(text); ret = g_malloc0(strlen(text) + count + 1); i = 0; j = 0; if (text[i] == '\n') ret[j++] = '\r'; ret[j++] = text[i++]; for (; i < strlen(text); i++) { if (text[i] == '\n' && text[i - 1] != '\r') ret[j++] = '\r'; ret[j++] = text[i]; } debug_printf("got: %s, leaving with %s\n", text, ret); return ret; } time_t get_time(int year, int month, int day, int hour, int min, int sec) { struct tm tm; tm.tm_year = year - 1900; tm.tm_mon = month - 1; tm.tm_mday = day; tm.tm_hour = hour; tm.tm_min = min; tm.tm_sec = sec >= 0 ? sec : time(NULL) % 60; return mktime(&tm); }