Import roominfo and roompic files into the database.
authorArt Cancro <ajc@citadel.org>
Tue, 19 Apr 2016 14:38:59 +0000 (10:38 -0400)
committerArt Cancro <ajc@citadel.org>
Tue, 19 Apr 2016 14:38:59 +0000 (10:38 -0400)
citadel/citadel.h
citadel/modules/ctdlproto/serv_rooms.c
citadel/modules/migrate/serv_migrate.c
citadel/modules/upgrade/serv_upgrade.c
citadel/room_ops.c
citadel/utillib/citadel_dirs.c
citadel/utils/ctdlmigrate.c

index 96422ac9684e4851bde75090739af9ece880cc9d..53606e3a34fa523f7a9ccb6bab1fca6f508f9f45 100644 (file)
@@ -134,7 +134,7 @@ struct ctdlroom {
        time_t QRgen;                   /* Generation number of room        */
        unsigned QRflags;               /* See flag values below            */
        char QRdirname[15];             /* Directory name, if applicable    */
-       long QRinfo;                    /* Info file update relative to msgs*/
+       long msgnum_info;               /* msgnum of room banner (info file)*/
        char QRfloor;                   /* Which floor this room is on      */
        time_t QRmtime;                 /* Date/time of last post           */
        struct ExpirePolicy QRep;       /* Message expiration policy        */
@@ -142,6 +142,7 @@ struct ctdlroom {
        char QRorder;                   /* Sort key for room listing order  */
        unsigned QRflags2;              /* Additional flags                 */
        int QRdefaultview;              /* How to display the contents      */
+       long msgnum_pic;                /* msgnum of room picture or icon   */
 };
 
 /* Private rooms are always flagged with QR_PRIVATE.  If neither QR_PASSWORDED
index 9df142cd04b96579a7c74468fbca82dccc2824d7..fa3d23ac43aac6fb4e52520c962627d3e2323eaf 100644 (file)
@@ -931,7 +931,6 @@ void cmd_einf(char *ok)
 
        /* now update the room index so people will see our new info */
        CtdlGetRoomLock(&CCC->room, CCC->room.QRname);          /* lock so no one steps on us */
-       CCC->room.QRinfo = CCC->room.QRhighest + 1L;
        CtdlPutRoomLock(&CCC->room);
 }
 
index 645c8d249cc939af46342b9789de0c23b2671c67..4ae75836b6e1a5c5db1dbbf0d6dcabfe43f83fe5 100644 (file)
@@ -157,7 +157,6 @@ void migr_export_rooms_backend(struct ctdlroom *buf, void *data) {
                xml_strout(buf->QRdirname);
                client_write(HKEY("</QRdirname>\n"));
        }
-       cprintf("<QRinfo>%ld</QRinfo>\n", buf->QRinfo);
        cprintf("<QRfloor>%d</QRfloor>\n", buf->QRfloor);
        cprintf("<QRmtime>%ld</QRmtime>\n", (long)buf->QRmtime);
        cprintf("<QRexpire_mode>%d</QRexpire_mode>\n", buf->QRep.expire_mode);
@@ -166,6 +165,8 @@ void migr_export_rooms_backend(struct ctdlroom *buf, void *data) {
        cprintf("<QRorder>%d</QRorder>\n", buf->QRorder);
        cprintf("<QRflags2>%u</QRflags2>\n", buf->QRflags2);
        cprintf("<QRdefaultview>%d</QRdefaultview>\n", buf->QRdefaultview);
+       cprintf("<msgnum_info>%ld</msgnum_info>\n", buf->msgnum_info);
+       cprintf("<msgnum_pic>%ld</msgnum_pic>\n", buf->msgnum_pic);
        client_write(HKEY("</room>\n"));
 
        /* message list goes inside this tag */
@@ -592,14 +593,13 @@ int migr_userrecord(void *data, const char *el)
 
 int migr_roomrecord(void *data, const char *el)
 {
-       if (!strcasecmp(el, "QRname"))                  safestrncpy(qrbuf.QRname, ChrPtr(migr_chardata), sizeof qrbuf.QRname);
+       if (!strcasecmp(el, "QRname"))                          safestrncpy(qrbuf.QRname, ChrPtr(migr_chardata), sizeof qrbuf.QRname);
        else if (!strcasecmp(el, "QRpasswd"))                   safestrncpy(qrbuf.QRpasswd, ChrPtr(migr_chardata), sizeof qrbuf.QRpasswd);
        else if (!strcasecmp(el, "QRroomaide"))                 qrbuf.QRroomaide = atol(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "QRhighest"))                  qrbuf.QRhighest = atol(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "QRgen"))                      qrbuf.QRgen = atol(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "QRflags"))                    qrbuf.QRflags = atoi(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "QRdirname"))                  safestrncpy(qrbuf.QRdirname, ChrPtr(migr_chardata), sizeof qrbuf.QRdirname);
-       else if (!strcasecmp(el, "QRinfo"))                     qrbuf.QRinfo = atol(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "QRfloor"))                    qrbuf.QRfloor = atoi(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "QRmtime"))                    qrbuf.QRmtime = atol(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "QRexpire_mode"))              qrbuf.QRep.expire_mode = atoi(ChrPtr(migr_chardata));
@@ -608,6 +608,8 @@ int migr_roomrecord(void *data, const char *el)
        else if (!strcasecmp(el, "QRorder"))                    qrbuf.QRorder = atoi(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "QRflags2"))                   qrbuf.QRflags2 = atoi(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "QRdefaultview"))              qrbuf.QRdefaultview = atoi(ChrPtr(migr_chardata));
+       else if (!strcasecmp(el, "msgnum_info"))                qrbuf.msgnum_info = atol(ChrPtr(migr_chardata));
+       else if (!strcasecmp(el, "msgnum_pic"))                 qrbuf.msgnum_pic = atol(ChrPtr(migr_chardata));
        else return 0;
        return 1;
 }
@@ -906,7 +908,6 @@ void migr_do_listdirs(void) {
        cprintf("messages|%s\n",        ctdl_message_dir);
        cprintf("keys|%s\n",            ctdl_key_dir);
        cprintf("images|%s\n",          ctdl_image_dir);
-       cprintf("info|%s\n",            ctdl_info_dir);
        cprintf("000\n");
 }
 
index 249c825053524575e3bf5b990a442bf9d88fc111..6526999275cd19827fbd1e0e3f9e8bb6afcf192c 100644 (file)
@@ -1,5 +1,8 @@
 /*
- * Transparently handle the upgrading of server data formats.
+ * Transparently handle the upgrading of server data formats.  If we see
+ * an existing version number of our database, we can make some intelligent
+ * guesses about what kind of data format changes need to be applied, and
+ * we apply them transparently.
  *
  * Copyright (c) 1987-2016 by the citadel.org team
  *
@@ -199,6 +202,176 @@ void guess_time_zone(void) {
 }
 
 
+
+/*
+ * Per-room callback function for ingest_old_roominfo_and_roompic_files()
+ *
+ * This is the second pass, where we process the list of rooms with info or pic files.
+ */
+void iorarf_oneroom(char *roomname, char *infofile, char *picfile)
+{
+       FILE *fp;
+       long data_length;
+       char *unencoded_data;
+       char *encoded_data;
+       long info_msgnum = 0;
+       long pic_msgnum = 0;
+       char subject[SIZ];
+
+       syslog(LOG_DEBUG, "iorarf_oneroom( %s , %s , %s )", roomname, infofile, picfile);
+
+       // Test for the presence of a legacy "room info file"
+       if (!IsEmptyStr(infofile)) {
+               fp = fopen(infofile, "r");
+       }
+       else {
+               fp = NULL;
+       }
+       if (fp) {
+               fseek(fp, 0, SEEK_END);
+               data_length = ftell(fp);
+
+               if (data_length >= 1) {
+                       rewind(fp);
+                       unencoded_data = malloc(data_length);
+                       if (unencoded_data) {
+                               fread(unencoded_data, data_length, 1, fp);
+                               encoded_data = malloc((data_length * 2) + 100);
+                               if (encoded_data) {
+                                       sprintf(encoded_data, "Content-type: text/plain\nContent-transfer-encoding: base64\n\n");
+                                       CtdlEncodeBase64(&encoded_data[strlen(encoded_data)], unencoded_data, data_length, 1);
+                                       snprintf(subject, sizeof subject, "Imported room banner for %s", roomname);
+                                       info_msgnum = quickie_message("Citadel", NULL, NULL, SYSCONFIGROOM, encoded_data, FMT_RFC822, subject);
+                                       free(encoded_data);
+                               }
+                               free(unencoded_data);
+                       }
+               }
+               fclose(fp);
+               // unlink(filename);
+       }
+
+       // Test for the presence of a legacy "room picture file" and import it.
+       if (!IsEmptyStr(picfile)) {
+               fp = fopen(picfile, "r");
+       }
+       else {
+               fp = NULL;
+       }
+       if (fp) {
+               fseek(fp, 0, SEEK_END);
+               data_length = ftell(fp);
+
+               if (data_length >= 1) {
+                       rewind(fp);
+                       unencoded_data = malloc(data_length);
+                       if (unencoded_data) {
+                               fread(unencoded_data, data_length, 1, fp);
+                               encoded_data = malloc((data_length * 2) + 100);
+                               if (encoded_data) {
+                                       sprintf(encoded_data, "Content-type: image/gif\nContent-transfer-encoding: base64\n\n");
+                                       CtdlEncodeBase64(&encoded_data[strlen(encoded_data)], unencoded_data, data_length, 1);
+                                       snprintf(subject, sizeof subject, "Imported room icon for %s", roomname);
+                                       pic_msgnum = quickie_message("Citadel", NULL, NULL, SYSCONFIGROOM, encoded_data, FMT_RFC822, subject);
+                                       free(encoded_data);
+                               }
+                               free(unencoded_data);
+                       }
+               }
+               fclose(fp);
+               // unlink(filename);
+       }
+
+       // Now we have the message numbers of our new banner and icon.  Record them in the room record.
+       // NOTE: we are not deleting the old msgnum_info because that position in the record was previously
+       // a pointer to the highest message number which existed in the room when the info file was saved,
+       // and we don't want to delete messages that are not *actually* old banners.
+       struct ctdlroom qrbuf;
+       if (CtdlGetRoomLock(&qrbuf, roomname) == 0) {
+               qrbuf.msgnum_info = info_msgnum;
+               qrbuf.msgnum_pic = pic_msgnum;
+               CtdlPutRoomLock(&qrbuf);
+       }
+
+}
+
+
+
+struct iorarf_list {
+       struct iorarf_list *next;
+       char name[ROOMNAMELEN];
+       char info[PATH_MAX];
+       char pic[PATH_MAX];
+};
+
+
+/*
+ * Per-room callback function for ingest_old_roominfo_and_roompic_files()
+ *
+ * This is the first pass, where the list of qualifying rooms is gathered.
+ */
+void iorarf_backend(struct ctdlroom *qrbuf, void *data)
+{
+       FILE *fp;
+       struct iorarf_list **iorarf_list = (struct iorarf_list **)data;
+
+       struct iorarf_list *i = malloc(sizeof(struct iorarf_list));
+       i->next = *iorarf_list;
+       strcpy(i->name, qrbuf->QRname);
+       strcpy(i->info, "");
+       strcpy(i->pic, "");
+
+       // Test for the presence of a legacy "room info file"
+       assoc_file_name(i->info, sizeof i->info, qrbuf, ctdl_info_dir);
+       fp = fopen(i->info, "r");
+       if (fp) {
+               fclose(fp);
+       }
+       else {
+               i->info[0] = 0;
+       }
+
+       // Test for the presence of a legacy "room picture file"
+       assoc_file_name(i->pic, sizeof i->pic, qrbuf, ctdl_image_dir);
+       fp = fopen(i->pic, "r");
+       if (fp) {
+               fclose(fp);
+       }
+       else {
+               i->pic[0] = 0;
+       }
+
+       if ( (!IsEmptyStr(i->info)) || (!IsEmptyStr(i->pic)) ) {
+               *iorarf_list = i;
+       }
+       else {
+               free(i);
+       }
+}
+
+
+/*
+ * Prior to Citadel Server version 902, room info and pictures (which comprise the
+ * displayed banner for each room) were stored in the filesystem.  If we are upgrading
+ * from version >000 to version >=902, ingest those files into the database.
+ */
+void ingest_old_roominfo_and_roompic_files(void)
+{
+       struct iorarf_list *il = NULL;
+
+       CtdlForEachRoom(iorarf_backend, &il);
+
+       struct iorarf_list *p;
+       while (il) {
+               iorarf_oneroom(il->name, il->info, il->pic);
+               p = il->next;
+               free(il);
+               il = p;
+       }
+
+}
+
+
 /*
  * Perform any upgrades that can be done automatically based on our knowledge of the previous
  * version of Citadel server that was running here.
@@ -300,6 +473,10 @@ void check_server_upgrades(void) {
                }
        }
 
+       if ((CtdlGetConfigInt("MM_hosted_upgrade_level") > 000) && (CtdlGetConfigInt("MM_hosted_upgrade_level") < 902)) {
+               ingest_old_roominfo_and_roompic_files();
+       }
+
        CtdlSetConfigInt("MM_hosted_upgrade_level", REV_LEVEL);
 
        /*
@@ -323,6 +500,7 @@ void check_server_upgrades(void) {
 CTDL_MODULE_UPGRADE(upgrade)
 {
        check_server_upgrades();
+       ingest_old_roominfo_and_roompic_files();        // FIXME remove this line, it's proper above!!!!
        
        /* return our module id for the Log */
        return "upgrade";
index ef185650b068201de2d1ba7ee889168e305cdd01..74adefb866690d56dce68c719e2d558f8c4df081 100644 (file)
@@ -826,8 +826,10 @@ void CtdlUserGoto(char *where, int display_result, int transiently,
        /* Check for new mail */
        newmailcount = NewMailCount();
 
-       /* set info to 1 if the user needs to read the room's info file */
-       if (CCC->room.QRinfo > vbuf.v_lastseen) {
+       /* Set info to 1 if the room banner is new since our last visit.
+        * Some clients only want to display it when it changes.
+        */
+       if (CCC->room.msgnum_info > vbuf.v_lastseen) {
                info = 1;
        }
 
index ab3701ac7d8da03729571d18f69feebf434bd5b2..faf70e6fef325525edd01a78ad32cfe7287a3704 100644 (file)
@@ -440,32 +440,18 @@ int create_dir(char *which, long ACCESS, long UID, long GID)
 
 int create_run_directories(long UID, long GID)
 {
-       int rv;
-
-       rv = create_dir(ctdl_info_dir    , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
-       if (rv != -1)
-               rv = create_dir(ctdl_message_dir   , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
-       if (rv != -1)
-               rv = create_dir(ctdl_hlp_dir       , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
-       if (rv != -1)
-               rv = create_dir(ctdl_image_dir     , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
-       if (rv != -1)
-               rv = create_dir(ctdl_bb_dir        , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
-       if (rv != -1)
-               rv = create_dir(ctdl_file_dir      , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
-       if (rv != -1)
-               rv = create_dir(ctdl_spool_dir     , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
-       if (rv != -1)
-               rv = create_dir(ctdl_netout_dir    , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
-       if (rv != -1)
-               rv = create_dir(ctdl_netin_dir     , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
-       if (rv != -1)
-               rv = create_dir(ctdl_netdigest_dir , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
-       if (rv != -1)
-               rv = create_dir(ctdl_nettmp_dir    , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
-       if (rv != -1)
-               rv = create_dir(ctdl_key_dir       , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
-       if (rv != -1)
-               rv = create_dir(ctdl_run_dir       , S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, UID, GID);
+       int rv = 0;
+       rv += create_dir(ctdl_message_dir   , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
+       rv += create_dir(ctdl_hlp_dir       , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
+       rv += create_dir(ctdl_image_dir     , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
+       rv += create_dir(ctdl_bb_dir        , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
+       rv += create_dir(ctdl_file_dir      , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
+       rv += create_dir(ctdl_spool_dir     , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
+       rv += create_dir(ctdl_netout_dir    , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
+       rv += create_dir(ctdl_netin_dir     , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
+       rv += create_dir(ctdl_netdigest_dir , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
+       rv += create_dir(ctdl_nettmp_dir    , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
+       rv += create_dir(ctdl_key_dir       , S_IRUSR|S_IWUSR|S_IXUSR, UID, -1);
+       rv += create_dir(ctdl_run_dir       , S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, UID, GID);
        return rv;
 }
index c3646c3e41614c45e64b752e5e7bf843ea9ab81e..199772ecc99b21c02e1ff89152209347d0583e63 100644 (file)
@@ -263,10 +263,6 @@ FAIL:      if (sourcefp) pclose(sourcefp);
                        snprintf(cmd, sizeof cmd, "rsync -va --rsh='ssh -S %s' %s@%s:%s/ %s/",
                                socket_path, remote_user, remote_host, &buf[7], ctdl_image_dir);
                }
-               else if (!strncasecmp(buf, "info|", 5)) {
-                       snprintf(cmd, sizeof cmd, "rsync -va --rsh='ssh -S %s' %s@%s:%s/ %s/",
-                               socket_path, remote_user, remote_host, &buf[5], ctdl_info_dir);
-               }
                else {
                        strcpy(cmd, "false");   /* cheap and sleazy way to throw an error */
                }