Back to index

courier  0.68.2
pref.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 2008 Double Precision, Inc.  See COPYING for
00003 ** distribution information.
00004 */
00005 
00006 
00007 /*
00008 */
00009 #include      "pref.h"
00010 #include      "config.h"
00011 #include      "auth.h"
00012 #include      "sqwebmail.h"
00013 #include      "sqconfig.h"
00014 #include      "mailinglist.h"
00015 #include      "cgi/cgi.h"
00016 #include      "pcp/pcp.h"
00017 #include      <stdio.h>
00018 #include      <string.h>
00019 #include      <stdlib.h>
00020 #include      <sys/stat.h>
00021 #include      <unistd.h>
00022 
00023 #define       OLDEST1ST     "OLDEST1ST"
00024 #define       FULLHEADERS   "FULLHEADERS"
00025 #define       SORTORDER     "SORT"
00026 #define       PAGESIZE      "PAGESIZE"
00027 #define       AUTOPURGE_V   "AUTOPURGE"
00028 #define       NOHTML        "NOHTML"
00029 #define       FROM          "FROM"
00030 #define       LDAP          "LDAP"
00031 #define FLOWEDTEXT   "NOFLOWEDTEXT"
00032 #define NOARCHIVE    "NOARCHIVE"
00033 #define NOAUTORENAMESENT    "NOAUTORENAMESENT"
00034 #define STARTOFWEEK  "STARTOFWEEK"
00035 #define WIKITEXT            "WIKITEXT"
00036 
00037 #define       OLDEST1ST_PREF       "oldest1st"
00038 #define       FULLHEADERS_PREF "fullheaders"
00039 #define       HTML_PREF "doshowhtml"
00040 #define FLOWEDTEXT_PREF "noflowedtext"
00041 #define NOARCHIVE_PREF "noarchive"
00042 #define NOAUTORENAMESENT_PREF "noautorenamesent"
00043 
00044 #define DEFAULTKEY   "DEFAULTKEY"
00045 
00046 int pref_flagisoldest1st, pref_flagfullheaders;
00047 int pref_showhtml;
00048 int pref_flagsortorder;
00049 int pref_flagpagesize;
00050 int pref_autopurge;
00051 int pref_noflowedtext;
00052 int pref_noarchive;
00053 int pref_noautorenamesent;
00054 int pref_startofweek;
00055 int pref_wikifmt;
00056 
00057 char *pref_from=0;
00058 char *pref_ldap=0;
00059 extern const char *sqwebmail_content_charset;
00060 
00061 #if ENABLE_WEBPASS
00062 extern int check_sqwebpass(const char *);
00063 extern void set_sqwebpass(const char *);
00064 #endif
00065 extern void output_attrencoded_oknl(const char *);
00066 extern const char *sqwebmail_mailboxid;
00067 extern void rename_sent_folder(int really);
00068 
00069 static const char hex[]="0123456789ABCDEF";
00070 
00071 static int nybble(char c)
00072 {
00073 char   *p=strchr(hex, c);
00074 
00075        if (p) return (p-hex);
00076        return (0);
00077 }
00078 
00079 static void decode(char *t)
00080 {
00081 char *s;
00082 
00083        for (s=t; *s; s++)
00084        {
00085               if (*s != '+')
00086               {
00087                      *t++ = *s;
00088                      continue;
00089               }
00090               if (s[1] == 0 || s[2] == 0)
00091                      continue;
00092               *t++ = nybble(s[1]) * 16 + nybble(s[2]);
00093               s += 2;
00094        }
00095        *t=0;
00096 }
00097 
00098 void pref_init()
00099 {
00100 const  char *p;
00101 char   *q, *r;
00102 
00103        p=read_sqconfig(".", CONFIGFILE, 0);
00104        pref_flagisoldest1st=0;
00105        pref_flagfullheaders=0;
00106        pref_flagsortorder=0;
00107        pref_flagpagesize=10;
00108        pref_noarchive=0;
00109 
00110        {
00111               const char *autorenamesent=AUTORENAMESENT;
00112 
00113               const char *p=getenv("SQWEBMAIL_AUTORENAMESENT");
00114               if (p && *p)
00115                      autorenamesent = p;
00116 
00117               pref_noautorenamesent=strncmp(autorenamesent, "no", 2) == 0;
00118        }
00119 
00120        pref_startofweek=0;
00121        pref_autopurge=AUTOPURGE;
00122        pref_showhtml=1;
00123        pref_wikifmt=0;
00124 
00125        if(pref_from) {
00126               free(pref_from);
00127               pref_from=0;
00128               }
00129 
00130        if(pref_ldap) {
00131               free(pref_ldap);
00132               pref_ldap=0;
00133               }
00134 
00135 
00136        if (p)
00137        {
00138               q=strdup(p);
00139               if (!q)       enomem();
00140 
00141               for (r=q; (r=strtok(r, " ")) != 0; r=0)
00142               {
00143                      if (strcmp(r, OLDEST1ST) == 0)
00144                             pref_flagisoldest1st=1;
00145                      if (strcmp(r, FULLHEADERS) == 0)
00146                             pref_flagfullheaders=1;
00147                      if (strcmp(r, NOHTML) == 0)
00148                             pref_showhtml=0;
00149                      if (strcmp(r, WIKITEXT) == 0)
00150                             pref_wikifmt=1;
00151 
00152                      if (strncmp(r, SORTORDER, sizeof(SORTORDER)-1) == 0
00153                             && r[sizeof(SORTORDER)-1] == '=')
00154                             pref_flagsortorder=r[sizeof(SORTORDER)];
00155                      if (strncmp(r, PAGESIZE, sizeof(PAGESIZE)-1) == 0
00156                             && r[sizeof(PAGESIZE)-1] == '=')
00157                             pref_flagpagesize=atoi(r+sizeof(PAGESIZE));
00158                      if (strncmp(r, AUTOPURGE_V, sizeof(AUTOPURGE_V)-1) == 0
00159                             && r[sizeof(AUTOPURGE_V)-1] == '=')
00160                             pref_autopurge=atoi(r+sizeof(AUTOPURGE_V));
00161                      if (strncmp(r, FLOWEDTEXT, sizeof(FLOWEDTEXT)-1) == 0
00162                             && r[sizeof(FLOWEDTEXT)-1] == '=')
00163                             pref_noflowedtext=atoi(r+sizeof(FLOWEDTEXT));
00164                      if (strncmp(r, NOARCHIVE, sizeof(NOARCHIVE)-1) == 0
00165                             && r[sizeof(NOARCHIVE)-1] == '=')
00166                             pref_noarchive=atoi(r+sizeof(NOARCHIVE));
00167                      if (strncmp(r, NOAUTORENAMESENT, sizeof(NOAUTORENAMESENT)-1) == 0
00168                             && r[sizeof(NOAUTORENAMESENT)-1] == '=')
00169                             pref_noautorenamesent=atoi(r+sizeof(NOAUTORENAMESENT));
00170                      if (strncmp(r, FROM, sizeof(FROM)-1) == 0
00171                             && r[sizeof(FROM)-1] == '=')
00172                      {
00173                             if (pref_from)       free(pref_from);
00174                             if ((pref_from=strdup(r+sizeof(FROM))) == 0)
00175                                    enomem();
00176 
00177                             decode(pref_from);
00178                      }
00179                      if (strncmp(r, LDAP, sizeof(LDAP)-1) == 0
00180                             && r[sizeof(LDAP)-1] == '=')
00181                      {
00182                             if (pref_ldap)       free(pref_ldap);
00183                             if ((pref_ldap=strdup(r+sizeof(LDAP))) == 0)
00184                                    enomem();
00185 
00186                             decode(pref_ldap);
00187                      }
00188                      if (strncmp(r, STARTOFWEEK, sizeof(STARTOFWEEK)-1) == 0
00189                             && r[sizeof(STARTOFWEEK)-1] == '=')
00190                      {
00191                             int n=atoi(r+sizeof(STARTOFWEEK));
00192 
00193                             if (n >= 0 && n < 7)
00194                                    pref_startofweek=n;
00195                      }
00196 
00197               }
00198               free(q);
00199        }
00200        switch (pref_flagpagesize)  {
00201        case 20:
00202        case 50:
00203        case 100:
00204        case 250:
00205               break;
00206        default:
00207               pref_flagpagesize=10;
00208               break;
00209        }
00210 
00211        if (pref_autopurge < 0)     pref_autopurge=0;
00212        if (pref_autopurge > MAXPURGE)     pref_autopurge=MAXPURGE;
00213 
00214        switch (pref_flagsortorder) {
00215        case 'F':
00216        case 'S':
00217               break;
00218        default:
00219               pref_flagsortorder='D';
00220               break;
00221        }
00222 }
00223 
00224 #if 0
00225 #if ENABLE_WEBPASS
00226 static int goodpass(const char *p)
00227 {
00228        for ( ; *p; p++)
00229               if (*p < ' ') return (0);
00230        return (1);
00231 }
00232 #endif
00233 #endif
00234 
00235 static char *append_str(const char *prefs, const char *label,
00236        const char *value)
00237 {
00238 int    l=strlen(prefs) + sizeof(" =") +
00239        strlen(label)+ (value ? strlen(value):0);
00240 int    i;
00241 char   *p;
00242 const char *q;
00243 
00244        for (i=0; value && value[i]; i++)
00245               if (value[i] <= ' ' || value[i] >= 127
00246                      || value[i] == '+')
00247                      l += 2;
00248 
00249        p=malloc(l);
00250        if (!p)       enomem();
00251        strcpy(p, prefs);
00252        if (!value || !*value)      return (p);
00253 
00254        strcat(strcat(strcat(p, " "), label), "=");
00255        i=strlen(p);
00256        for (q=value; *q; q++)
00257        {
00258               if (*q <= ' ' || *q >= 127 || *q == '+')
00259               {
00260                      sprintf(p+i, "+%02X", (int)(unsigned char)*q);
00261                      i += 3;
00262                      continue;
00263               }
00264               p[i++]= *q;
00265        }
00266        p[i]=0;
00267        return (p);
00268 }
00269 
00270 void pref_update()
00271 {
00272 char   buf[1000];
00273 char   *p;
00274 char   *q;
00275 
00276        sprintf(buf, SORTORDER "=%c " PAGESIZE "=%d " AUTOPURGE_V "=%d "
00277               FLOWEDTEXT "=%d " NOARCHIVE "=%d " NOAUTORENAMESENT "=%d "
00278               STARTOFWEEK "=%d",
00279               pref_flagsortorder, pref_flagpagesize, pref_autopurge,
00280               pref_noflowedtext, pref_noarchive, pref_noautorenamesent,
00281               pref_startofweek);
00282 
00283        if (pref_flagisoldest1st)
00284               strcat(buf, " " OLDEST1ST);
00285 
00286        if (pref_flagfullheaders)
00287               strcat(buf, " " FULLHEADERS);
00288 
00289        if (!pref_showhtml)
00290               strcat(buf, " " NOHTML);
00291 
00292        if (pref_wikifmt)
00293               strcat(buf, " " WIKITEXT);
00294 
00295        p=append_str(buf, FROM, pref_from);
00296        q=append_str(p, LDAP, pref_ldap);
00297        write_sqconfig(".", CONFIGFILE, q);
00298        free(q);
00299        free(p);
00300 }
00301 
00302 void pref_setfrom(const char *p)
00303 {
00304        if (pref_from)       free(pref_from);
00305        pref_from=strdup(p);
00306        if (!pref_from)      enomem();
00307        pref_update();
00308 }
00309 
00310 void pref_setldap(const char *p)
00311 {
00312        if (pref_ldap && strcmp(p, pref_ldap) == 0)
00313               return;
00314 
00315        if (pref_ldap)       free(pref_ldap);
00316        pref_ldap=strdup(p);
00317        if (!pref_ldap)      enomem();
00318        pref_update();
00319 }
00320 
00321 void pref_setprefs()
00322 {
00323        if (*cgi("do.changeprefs"))
00324        {
00325        char   buf[1000];
00326        FILE   *fp;
00327        char   *p;
00328        char   *q;
00329 
00330               sprintf(buf, SORTORDER "=%c " PAGESIZE "=%s " AUTOPURGE_V "=%s "
00331                      FLOWEDTEXT "=%s "
00332                      NOARCHIVE "=%s "
00333                      NOAUTORENAMESENT "=%s "
00334                      STARTOFWEEK "=%d",
00335                      *cgi("sortorder"), cgi("pagesize"), cgi("autopurge"),
00336                      *cgi(FLOWEDTEXT_PREF) ? "1":"0",
00337                      *cgi(NOARCHIVE_PREF) ? "1":"0",
00338                      *cgi(NOAUTORENAMESENT_PREF) ? "1":"0",
00339                      (int)((unsigned)atoi(cgi(STARTOFWEEK)) % 7)
00340                      );
00341 
00342               if (*cgi(OLDEST1ST_PREF))
00343                      strcat(buf, " " OLDEST1ST);
00344               if (*cgi(FULLHEADERS_PREF))
00345                      strcat(buf, " " FULLHEADERS);
00346               if (!*cgi(HTML_PREF))
00347                      strcat(buf, " " NOHTML);
00348 
00349               p=append_str(buf, FROM, pref_from);
00350               q=append_str(p, LDAP, pref_ldap);
00351               write_sqconfig(".", CONFIGFILE, q);
00352               free(p);
00353               free(q);
00354               pref_init();
00355               if ((fp=fopen(SIGNATURE, "w")) != NULL)
00356               {
00357                      char *sig_utf8=
00358                             libmail_u_convert_toutf8(cgi("signature"),
00359                                                   sqwebmail_content_charset,
00360                                                   NULL);
00361 
00362                      if (sig_utf8)
00363                      {
00364                             fprintf(fp, "%s", sig_utf8);
00365                             free(sig_utf8);
00366                      }
00367                      fclose(fp);
00368               }
00369 
00370               savemailinglists(cgi("mailinglists"));
00371 
00372               printf("%s\n", getarg("PREFSOK"));
00373 
00374               rename_sent_folder(0);
00375        }
00376 
00377        if (*cgi("do.changepwd"))
00378        {
00379               int status=1;
00380               const  char *p=cgi("newpass");
00381               int has_syspwd=0;
00382 
00383               if ( *p && strcmp(p, cgi("newpass2")) == 0
00384                      && strlen(p) >= MINPASSLEN)
00385               {
00386                      has_syspwd=
00387                             login_changepwd(sqwebmail_mailboxid,
00388                                           cgi("oldpass"), p,
00389                                           &status);
00390               }
00391 
00392               if (has_syspwd || status)
00393               {
00394                      printf("%s\n", getarg("PWDERR"));
00395               }
00396               else
00397               {
00398                      printf("%s\n", getarg("PWDOK"));
00399               }
00400        }
00401 
00402 #if 0
00403        if (*cgi("do.changepwd"))
00404        {
00405 #if ENABLE_WEBPASS
00406 
00407        const  char *p;
00408 
00409               if (check_sqwebpass(cgi("oldpass")) == 0 &&
00410                      *(p=cgi("newpass")) &&
00411                      goodpass(p) &&
00412                      strcmp(p, cgi("newpass2")) == 0)
00413               {
00414                      set_sqwebpass(p);
00415               }
00416               else
00417               {
00418                      printf("%s\n", getarg("PWDERR"));
00419               }
00420 #else
00421               printf("%s\n", getarg("PWDERR"));
00422 #endif
00423        }
00424 #endif
00425 }
00426 
00427 void pref_isoldest1st()
00428 {
00429        printf("<input type=\"checkbox\" name=\"%s\" id=\"%s\"%s />",
00430               OLDEST1ST_PREF, OLDEST1ST_PREF, pref_flagisoldest1st ? " checked=\"checked\"":"");
00431 }
00432 
00433 void pref_isdisplayfullmsg()
00434 {
00435        printf("<input type=\"checkbox\" name=\"%s\" id=\"%s\"%s />",
00436               FULLHEADERS_PREF, FULLHEADERS_PREF, pref_flagfullheaders ? " checked=\"checked\"":"");
00437 }
00438 
00439 void pref_displayhtml()
00440 {
00441        printf("<input type=\"checkbox\" name=\"%s\" id=\"%s\"%s />",
00442               HTML_PREF, HTML_PREF, pref_showhtml ? " checked=\"checked\"":"");
00443 }
00444 
00445 void pref_displayflowedtext()
00446 {
00447        printf("<input type=\"checkbox\" name=\"%s\" id=\"%s\"%s />",
00448               FLOWEDTEXT_PREF, FLOWEDTEXT_PREF, pref_noflowedtext ? " checked=\"checked\"":"");
00449 }
00450 
00451 void pref_displayweekstart()
00452 {
00453        int i, j;
00454        static const int d[3]={6,0,1};
00455 
00456        printf("<select name=\"" STARTOFWEEK "\">");
00457 
00458        for (j=0; j<3; j++)
00459        {
00460               i=d[j];
00461               printf("<option value=\"%d\"%s>", i,
00462                      i == pref_startofweek ? " selected='selected'":"");
00463 
00464               output_attrencoded_oknl( pcp_wdayname_long(i));
00465               printf("</option>");
00466        }
00467        printf("</select>");
00468 }
00469 
00470 void pref_displaynoarchive()
00471 {
00472        printf("<input type=\"checkbox\" name=\"%s\" id=\"%s\"%s />",
00473               NOARCHIVE_PREF, NOARCHIVE_PREF, pref_noarchive ? " checked=\"checked\"":"");
00474 }
00475 
00476 void pref_displaynoautorenamesent()
00477 {
00478        printf("<input type=\"checkbox\" name=\"%s\" id=\"%s\"%s />",
00479               NOAUTORENAMESENT_PREF, NOAUTORENAMESENT_PREF, pref_noautorenamesent ? " checked=\"checked\"":"");
00480 }
00481 
00482 void pref_displayautopurge()
00483 {
00484        printf("<input type=\"text\" name=\"autopurge\" value=\"%d\" size=\"2\" maxlength=\"2\" />",
00485               pref_autopurge);
00486 }
00487 
00488 void pref_sortorder()
00489 {
00490 static const char selected[]=" selected='selected'";
00491 
00492        printf("<select name=\"sortorder\">");
00493        printf("<option value=\"DATE\"%s>%s</option>\n",
00494               pref_flagsortorder == 'D' ? selected:"",
00495               getarg("DATE"));
00496 
00497        printf("<option value=\"FROM\"%s>%s</option>\n",
00498               pref_flagsortorder == 'F' ? selected:"",
00499               getarg("SENDER"));
00500        printf("<option value=\"SUBJECT\"%s>%s</option>\n",
00501               pref_flagsortorder == 'S' ? selected:"",
00502               getarg("SUBJECT"));
00503        printf("</select>\n");
00504 }
00505 
00506 void pref_pagesize()
00507 {
00508 static const char selected[]=" selected='selected'";
00509 
00510        printf("<select name=\"pagesize\">");
00511        printf("<option value=\"10\"%s>10</option>\n",
00512               pref_flagpagesize == 10 ? selected:"");
00513        printf("<option value=\"20\"%s>20</option>\n",
00514               pref_flagpagesize == 20 ? selected:"");
00515        printf("<option value=\"50\"%s>50</option>\n",
00516               pref_flagpagesize == 50 ? selected:"");
00517        printf("<option value=\"100\"%s>100</option>\n",
00518               pref_flagpagesize == 100 ? selected:"");
00519        printf("<option value=\"250\"%s>250</option>\n",
00520               pref_flagpagesize == 250 ? selected:"");
00521        printf("</select>\n");
00522 }
00523 
00524 char *pref_getsig()
00525 {
00526        return pref_getfile(fopen(SIGNATURE, "r"));
00527 }
00528 
00529 char *pref_getfile(FILE *fp)
00530 {
00531        struct stat st;
00532        char *utf8_buf;
00533        char *sig_buf;
00534 
00535        if (fp == NULL)
00536               return NULL;
00537 
00538        if (fstat(fileno(fp), &st) < 0)
00539        {
00540               fclose(fp);
00541               return NULL;
00542        }
00543 
00544        utf8_buf=malloc(st.st_size+1);
00545 
00546        if (!utf8_buf)
00547        {
00548               fclose(fp);
00549               return NULL;
00550        }
00551 
00552        if (fread(utf8_buf, 1, st.st_size, fp) != st.st_size)
00553        {
00554               fclose(fp);
00555               return NULL;
00556        }
00557        utf8_buf[st.st_size]=0;
00558        fclose(fp);
00559 
00560        sig_buf=libmail_u_convert_fromutf8(utf8_buf,
00561                                       sqwebmail_content_charset,
00562                                       NULL);
00563        free(utf8_buf);
00564 
00565        return sig_buf;
00566 }
00567 
00568 void pref_signature()
00569 {
00570        char *p=pref_getsig();
00571 
00572        if (p)
00573        {
00574               output_attrencoded_oknl(p);
00575               free(p);
00576        }
00577 }
00578 /*
00579 ** Get a setting from GPGCONFIGFILE
00580 **
00581 ** GPGCONFIGFILE consists of space-separated settings.
00582 */
00583 
00584 static char *getgpgconfig(const char *name)
00585 {
00586        const char *p;
00587        char   *q, *r;
00588 
00589        int name_l=strlen(name);
00590 
00591        p=read_sqconfig(".", GPGCONFIGFILE, 0);
00592 
00593        if (p)
00594        {
00595               q=strdup(p);
00596               if (!q)
00597                      enomem();
00598 
00599               for (r=q; (r=strtok(r, " ")) != NULL; r=NULL)
00600                      if (strncmp(r, name, name_l) == 0 &&
00601                          r[name_l] == '=')
00602                      {
00603                             r=strdup(r+name_l+1);
00604                             free(q);
00605                             if (!r)
00606                                    enomem();
00607                             return (r);
00608                      }
00609               free(q);
00610        }
00611        return (NULL);
00612 }
00613 
00614 /*
00615 ** Enter a setting into GPGCONFIGFILE
00616 */
00617 
00618 static void setgpgconfig(const char *name, const char *value)
00619 {
00620        const  char *p;
00621        char *q, *r, *s;
00622        int name_l=strlen(name);
00623 
00624        /* Get the existing settings */
00625 
00626        p=read_sqconfig(".", GPGCONFIGFILE, 0);
00627 
00628        if (!p)
00629               p="";
00630 
00631        q=strdup(p);
00632        if (!q)
00633               enomem();
00634 
00635        s=malloc(strlen(q)+strlen(name)+strlen(value)+4);
00636        if (!s)
00637               enomem();
00638        *s=0;
00639 
00640        /*
00641        ** Copy existing settings into a new buffer, deleting any old
00642        ** setting.
00643        */
00644 
00645        for (r=q; (r=strtok(r, " ")) != NULL; r=NULL)
00646        {
00647               if (strncmp(r, name, name_l) == 0 &&
00648                   r[name_l] == '=')
00649               {
00650                      continue;
00651               }
00652 
00653               if (*s)
00654                      strcat(s, " ");
00655               strcat(s, r);
00656        }
00657 
00658        /* Append the new setting */
00659 
00660        if (*s)
00661               strcat(s, " ");
00662        strcat(strcat(strcat(s, name), "="), value);
00663        free(q);
00664        write_sqconfig(".", GPGCONFIGFILE, s);
00665        free(s);
00666 }
00667 
00668 char *pref_getdefaultgpgkey()
00669 {
00670        return (getgpgconfig(DEFAULTKEY));
00671 }
00672 
00673 void pref_setdefaultgpgkey(const char *v)
00674 {
00675        setgpgconfig(DEFAULTKEY, v);
00676 }