"Fossies" - the Fresh Open Source Software Archive

Member "citadel/modules/bio/serv_bio.c" (5 Jun 2021, 6620 Bytes) of package /linux/www/citadel.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "serv_bio.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.01_vs_902.

    1 /*
    2  * This module implementsserver commands related to the display and
    3  * manipulation of user "bio" files.
    4  *
    5  * Copyright (c) 1987-2021 by the citadel.org team
    6  *
    7  * This program is open source software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 3 of the License, or
   10  * (at your option) any later version.
   11  *
   12  * This program is distributed in the hope that it will be useful,
   13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15  * GNU General Public License for more details.
   16  */
   17 
   18 #include "ctdl_module.h"
   19 #include "config.h"
   20 
   21 #include <sys/types.h>
   22 #include <sys/stat.h>
   23 #include <dirent.h>
   24 
   25 
   26 /*
   27  * Command to enter user bio (profile) in plain text.
   28  * This is deprecated , or at least it will be when its replacement is written  :)
   29  * I want commands to get/set bio in full MIME wonderfulness.
   30  */
   31 void cmd_ebio(char *cmdbuf) {
   32     char buf[SIZ];
   33 
   34     unbuffer_output();
   35 
   36     if (!(CC->logged_in)) {
   37         cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN);
   38         return;
   39     }
   40 
   41     StrBuf *NewProfile = NewStrBufPlain("Content-type: text/plain; charset=UTF-8\nContent-transfer-encoding: 8bit\n\n", -1);
   42 
   43     cprintf("%d Transmit user profile in plain text now.\n", SEND_LISTING);
   44     while(client_getln(buf, sizeof buf) >= 0 && strcmp(buf,"000")) {
   45         StrBufAppendBufPlain(NewProfile, buf, -1, 0);
   46         StrBufAppendBufPlain(NewProfile, HKEY("\n"), 0);
   47     }
   48 
   49     /* we have read the new profile from the user , now save it */
   50     long old_msgnum = CC->user.msgnum_bio;
   51     char userconfigroomname[ROOMNAMELEN];
   52     CtdlMailboxName(userconfigroomname, sizeof userconfigroomname, &CC->user, USERCONFIGROOM);
   53     long new_msgnum = quickie_message("Citadel", NULL, NULL, userconfigroomname, ChrPtr(NewProfile), FMT_RFC822, "Profile submitted with EBIO command");
   54     FreeStrBuf(&NewProfile);
   55     CtdlGetUserLock(&CC->user, CC->curr_user);
   56     CC->user.msgnum_bio = new_msgnum;
   57     CtdlPutUserLock(&CC->user);
   58     if (old_msgnum > 0) {
   59         syslog(LOG_DEBUG, "Deleting old message %ld from %s", old_msgnum, userconfigroomname);
   60         CtdlDeleteMessages(userconfigroomname, &old_msgnum, 1, "");
   61     }
   62 }
   63 
   64 
   65 /*
   66  * Command to read user bio (profile) in plain text.
   67  * This is deprecated , or at least it will be when its replacement is written  :)
   68  * I want commands to get/set bio in full MIME wonderfulness.
   69  */
   70 void cmd_rbio(char *cmdbuf)
   71 {
   72     struct ctdluser ruser;
   73     char buf[SIZ];
   74 
   75     extract_token(buf, cmdbuf, 0, '|', sizeof buf);
   76     if (CtdlGetUser(&ruser, buf) != 0) {
   77         cprintf("%d No such user.\n",ERROR + NO_SUCH_USER);
   78         return;
   79     }
   80 
   81     cprintf("%d OK|%s|%ld|%d|%ld|%ld|%ld\n", LISTING_FOLLOWS,
   82         ruser.fullname, ruser.usernum, ruser.axlevel,
   83         (long)ruser.lastcall, ruser.timescalled, ruser.posted);
   84 
   85     struct CtdlMessage *msg = CtdlFetchMessage(ruser.msgnum_bio, 1);
   86     if (msg != NULL) {
   87         CtdlOutputPreLoadedMsg(msg, MT_CITADEL, HEADERS_NONE, 0, 0, 0);
   88         CM_Free(msg);
   89     }
   90     cprintf("000\n");
   91 }
   92 
   93 
   94 /*
   95  * Import function called by import_old_bio_files() for a single user
   96  */
   97 void import_one_bio_file(char *username, long usernum, char *path)
   98 {
   99     syslog(LOG_DEBUG, "Import legacy bio for %s, usernum=%ld, filename=%s", username, usernum, path);
  100 
  101     FILE *fp = fopen(path, "r");
  102     if (!fp) return;
  103 
  104     fseek(fp, 0, SEEK_END);
  105     long data_length = ftell(fp);
  106 
  107     if (data_length >= 1) {
  108         rewind(fp);
  109         char *unencoded_data = malloc(data_length);
  110         if (unencoded_data) {
  111             fread(unencoded_data, data_length, 1, fp);
  112             char *encoded_data = malloc((data_length * 2) + 100);
  113             if (encoded_data) {
  114                 sprintf(encoded_data, "Content-type: text/plain; charset=UTF-8\nContent-transfer-encoding: base64\n\n");
  115                 CtdlEncodeBase64(&encoded_data[strlen(encoded_data)], unencoded_data, data_length, 1);
  116 
  117                 char userconfigroomname[ROOMNAMELEN];
  118                 struct ctdluser usbuf;
  119 
  120                 if (CtdlGetUser(&usbuf, username) == 0) {   // no need to lock it , we are still initializing
  121                     long old_msgnum = usbuf.msgnum_bio;
  122                     CtdlMailboxName(userconfigroomname, sizeof userconfigroomname, &usbuf, USERCONFIGROOM);
  123                     long new_msgnum = quickie_message("Citadel", NULL, NULL, userconfigroomname, encoded_data, FMT_RFC822, "Profile imported from bio");
  124                     syslog(LOG_DEBUG, "Message %ld is now the profile for %s", new_msgnum, username);
  125                     usbuf.msgnum_bio = new_msgnum;
  126                     CtdlPutUser(&usbuf);
  127                     unlink(path);               // delete the old file , it's in the database now
  128                     if (old_msgnum > 0) {
  129                         syslog(LOG_DEBUG, "Deleting old message %ld from %s", old_msgnum, userconfigroomname);
  130                         CtdlDeleteMessages(userconfigroomname, &old_msgnum, 1, "");
  131                     }
  132                 }
  133                 free(encoded_data);
  134             }
  135             free(unencoded_data);
  136         }
  137     }
  138     fclose(fp);
  139 }
  140 
  141 
  142 /*
  143  * Look for old-format "bio" files and import them into the message base
  144  */
  145 void import_old_bio_files(void)
  146 {
  147     DIR *filedir = NULL;
  148     struct dirent *filedir_entry;
  149     size_t d_namelen;
  150     struct ctdluser usbuf;
  151     long usernum = 0;
  152     int d_type = 0;
  153     struct stat s;
  154     char path[PATH_MAX];
  155 
  156 
  157     syslog(LOG_DEBUG, "Importing old style bio files into the message base");
  158     filedir = opendir("bio");
  159     if (filedir == NULL) {
  160         return;
  161     }
  162     while ( (filedir_entry = readdir(filedir)) , (filedir_entry != NULL))
  163     {
  164 #ifdef _DIRENT_HAVE_D_NAMLEN
  165         d_namelen = filedir_entry->d_namlen;
  166 
  167 #else
  168         d_namelen = strlen(filedir_entry->d_name);
  169 #endif
  170 
  171 #ifdef _DIRENT_HAVE_D_TYPE
  172         d_type = filedir_entry->d_type;
  173 #else
  174 
  175 #ifndef DT_UNKNOWN
  176 #define DT_UNKNOWN     0
  177 #define DT_DIR         4
  178 #define DT_REG         8
  179 #define DT_LNK         10
  180 
  181 #define IFTODT(mode)   (((mode) & 0170000) >> 12)
  182 #define DTTOIF(dirtype)        ((dirtype) << 12)
  183 #endif
  184         d_type = DT_UNKNOWN;
  185 #endif
  186         if ((d_namelen == 1) && 
  187             (filedir_entry->d_name[0] == '.'))
  188             continue;
  189 
  190         if ((d_namelen == 2) && 
  191             (filedir_entry->d_name[0] == '.') &&
  192             (filedir_entry->d_name[1] == '.'))
  193             continue;
  194 
  195         snprintf(path, PATH_MAX, "bio/%s", filedir_entry->d_name);
  196         if (d_type == DT_UNKNOWN) {
  197             if (lstat(path, &s) == 0) {
  198                 d_type = IFTODT(s.st_mode);
  199             }
  200         }
  201         switch (d_type)
  202         {
  203         case DT_DIR:
  204             break;
  205         case DT_LNK:
  206         case DT_REG:
  207             usernum = atol(filedir_entry->d_name);
  208             if (CtdlGetUserByNumber(&usbuf, usernum) == 0) {
  209                 import_one_bio_file(usbuf.fullname, usernum, path);
  210             }
  211         }
  212     }
  213     closedir(filedir);
  214     rmdir("bio");
  215 }
  216 
  217 
  218 
  219 CTDL_MODULE_INIT(bio)
  220 {
  221     if (!threading)
  222     {
  223         import_old_bio_files();
  224             CtdlRegisterProtoHook(cmd_ebio, "EBIO", "Enter your bio");
  225             CtdlRegisterProtoHook(cmd_rbio, "RBIO", "Read a user's bio");
  226     }
  227     /* return our module name for the log */
  228         return "bio";
  229 }