]> code.citadel.org Git - citadel.git/blobdiff - citadel/textclient/messages.c
mini rfc2047 decoder for the text client
[citadel.git] / citadel / textclient / messages.c
index 3359d75144c51512192a159f77be4a89c7022e57..e20888f29097636081056310e7231ad5efafb93f 100644 (file)
@@ -1,21 +1,15 @@
 /*
  * Text client functions for reading and writing of messages
  *
- * Copyright (c) 1987-2010 by the citadel.org team
+ * Copyright (c) 1987-2012 by the citadel.org team
  *
- * 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 3 of the License, or
- * (at your option) any later version.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
  * 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
  */
 
 #include "sysdep.h"
@@ -363,7 +357,10 @@ void citedit(FILE *fp)
        putc(10, fp);
        fflush(fp);
        rv = ftruncate(fileno(fp), ftell(fp));
+       if (rv < 0)
+               scr_printf("failed to set message buffer: %s\n", strerror(errno));
 
+       
        /* and deallocate the memory we used */
        while (textlist != NULL) {
                ptr = textlist->next;
@@ -390,6 +387,50 @@ void free_parts(struct parts *p)
 }
 
 
+/*
+ * This is a mini RFC2047 decoder.
+ * It only handles strings encoded from UTF-8 as Quoted-printable.
+ */
+void mini_2047_decode(char *s) {
+       if (!s) return;
+
+       char *qstart = strstr(s, "=?UTF-8?Q?");
+       if (!qstart) return;
+
+       char *qend = strstr(s, "?=");
+       if (!qend) return;
+
+       if (qend <= qstart) return;
+
+       strcpy(qstart, &qstart[10]);
+       qend -= 10;
+
+       char *p = qstart;
+       while (p < qend) {
+
+               if (p[0] == '=') {
+
+                       char ch[3];
+                       ch[0] = p[1];
+                       ch[1] = p[2];
+                       ch[2] = p[3];
+                       int c;
+                       sscanf(ch, "%02x", &c);
+                       p[0] = c;
+                       strcpy(&p[1], &p[3]);
+                       qend -= 2;
+               }
+
+               if (p[0] == '_') {
+                       p[0] = ' ';
+               }
+               
+               ++p;
+       }
+
+       strcpy(qend, &qend[2]);
+}
+
 /*
  * Read a message from the server
  */
@@ -471,7 +512,8 @@ int read_message(CtdlIPC *ipc,
                                scr_printf("part=%s|%s|%s|%s|%s|%ld\n",
                                        ptr->name, ptr->filename, ptr->number,
                                        ptr->disposition, ptr->mimetype,
-                                       ptr->length);
+                                       ptr->length
+                               );
                        }
                }
                scr_printf("\n");
@@ -610,12 +652,12 @@ int read_message(CtdlIPC *ipc,
                safestrncpy(reply_subject, message->subject, sizeof reply_subject);
                if (!IsEmptyStr(message->subject)) {
                        if (dest) {
-                               fprintf(dest, "Subject: %s\n",
-                                                       message->subject);
+                               fprintf(dest, "Subject: %s\n", message->subject);
                        } else {
                                color(DIM_WHITE);
                                scr_printf("Subject: ");
                                color(BRIGHT_CYAN);
+                               mini_2047_decode(message->subject);
                                scr_printf("%s\n", message->subject);
                        }
                }
@@ -801,6 +843,10 @@ void replace_string(char *filename, long int startpos)
                        rpos = ftell(fp);
                        fseek(fp, wpos, 0);
                        rv = fwrite((char *) buf, 128, 1, fp);
+                       if (rv < 0) {
+                               scr_printf("failed to replace string: %s\n", strerror(errno));
+                               break; /*whoopsi! */
+                       }
                        strcpy(buf, &buf[128]);
                        wpos = ftell(fp);
                        fseek(fp, rpos, 0);
@@ -877,8 +923,6 @@ int client_make_message(CtdlIPC *ipc,
                newprompt("Subject: ", subject, 70);
        }
 
-       beg = 0L;
-
        if (mode == 1) {
                scr_printf("(Press ctrl-d when finished)\n");
        }
@@ -888,6 +932,9 @@ int client_make_message(CtdlIPC *ipc,
                if (fp != NULL) {
                        fmout(screenwidth, fp, NULL, NULL, 0);
                        beg = ftell(fp);
+                       if (beg < 0)
+                               scr_printf("failed to get stream position %s\n", 
+                                          strerror(errno));
                        fclose(fp);
                } else {
                        fp = fopen(filename, "w");
@@ -1001,6 +1048,9 @@ MECR:     if (mode >= 2) {
                if (fp != NULL) {
                        fmout(screenwidth, fp, NULL, NULL, 0);
                        beg = ftell(fp);
+                       if (beg < 0)
+                               scr_printf("failed to get stream position %s\n", 
+                                          strerror(errno));
                        fclose(fp);
                }
                goto MECR;
@@ -1362,6 +1412,8 @@ void list_urls(CtdlIPC *ipc)
 
        snprintf(cmd, sizeof cmd, rc_url_cmd, urls[i - 1]);
        rv = system(cmd);
+       if (rv != 0) 
+               scr_printf("failed to '%s' by %d\n", cmd, rv);
        scr_printf("\n");
 }
 
@@ -1497,7 +1549,7 @@ void readmsgs(CtdlIPC *ipc,
        enum MessageDirection rdir,     /* 1=Forward (-1)=Reverse */
        int q           /* Number of msgs to read (if c==3) */
 ) {
-       int a, b, e, f, g, start;
+       int a, e, f, g, start;
        int savedpos;
        int hold_sw = 0;
        char arcflag = 0;
@@ -1515,11 +1567,6 @@ void readmsgs(CtdlIPC *ipc,
        static int att_seq = 0;         /* Attachment download sequence number */
        int rv = 0;                     /* silence the stupid warn_unused_result warnings */
 
-       if (c < 0)
-               b = (num_msgs - 1);
-       else
-               b = 0;
-
        CtdlMakeTempFileName(prtfile, sizeof prtfile);
 
        if (msg_arr) {
@@ -1579,7 +1626,7 @@ RAGAIN:           pagin = ((arcflag == 0)
                if ((quotflag) || (arcflag)) {
                        screenwidth = hold_sw;
                }
-RMSGREAD:      scr_flush();
+RMSGREAD:
                highest_msg_read = msg_arr[a];
                if (quotflag) {
                        fclose(dest);
@@ -1729,7 +1776,6 @@ RMSGREAD: scr_flush();
                                scr_printf("\r%79s\r", "");
                        else
                                scr_printf("\n");
-                       scr_flush();
                }
 DONE_QUOTING:  switch (e) {
                case '?':
@@ -1827,6 +1873,8 @@ DONE_QUOTING:     switch (e) {
                                        save_buffer(attachment, extract_unsigned_long(cmd, 0), save_to);
                                        snprintf(cmd, sizeof cmd, rc_open_cmd, save_to);
                                        rv = system(cmd);
+                                       if (rv != 0)
+                                               scr_printf("failed to save %s Reason %d\n", cmd, rv);
                                }
                                else {                  /* save attachment to disk */
                                        destination_directory(save_to, filename);