X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fbio%2Fserv_bio.c;h=e6e1dd20b103112d9adaae16d9bd90b1ba77b1fc;hb=f614f64351a5df98ebc837c973772cebb8171bd4;hp=a3a9c6a61646de1d59a99da4f89bea89ca34e4fc;hpb=6106c1da54f0923550c7bdceb45246fb88e9ea19;p=citadel.git diff --git a/citadel/modules/bio/serv_bio.c b/citadel/modules/bio/serv_bio.c index a3a9c6a61..e6e1dd20b 100644 --- a/citadel/modules/bio/serv_bio.c +++ b/citadel/modules/bio/serv_bio.c @@ -2,124 +2,228 @@ * This module implementsserver commands related to the display and * manipulation of user "bio" files. * + * Copyright (c) 1987-2021 by the citadel.org team * - * Copyright (c) 1987-2009 by the citadel.org team + * This program is open source 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 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 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 + * 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. */ #include "ctdl_module.h" +#include "config.h" +#include +#include +#include /* - * enter user bio + * Command to enter user bio (profile) in plain text. + * This is deprecated , or at least it will be when its replacement is written :) + * I want commands to get/set bio in full MIME wonderfulness. */ void cmd_ebio(char *cmdbuf) { char buf[SIZ]; - FILE *fp; unbuffer_output(); if (!(CC->logged_in)) { - cprintf("%d Not logged in.\n",ERROR + NOT_LOGGED_IN); + cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN); return; } - snprintf(buf, sizeof buf, "%s%ld",ctdl_bio_dir,CC->user.usernum); - fp = fopen(buf,"w"); - if (fp == NULL) { - cprintf("%d Cannot create file: %s\n", ERROR + INTERNAL_ERROR, - strerror(errno)); - return; - } - cprintf("%d \n",SEND_LISTING); + StrBuf *NewProfile = NewStrBufPlain("Content-type: text/plain; charset=UTF-8\nContent-transfer-encoding: 8bit\n\n", -1); + + cprintf("%d Transmit user profile in plain text now.\n", SEND_LISTING); while(client_getln(buf, sizeof buf) >= 0 && strcmp(buf,"000")) { - if (ftell(fp) < config.c_maxmsglen) { - fprintf(fp,"%s\n",buf); - } + StrBufAppendBufPlain(NewProfile, buf, -1, 0); + StrBufAppendBufPlain(NewProfile, HKEY("\n"), 0); + } + + /* we have read the new profile from the user , now save it */ + long old_msgnum = CC->user.msgnum_bio; + char userconfigroomname[ROOMNAMELEN]; + CtdlMailboxName(userconfigroomname, sizeof userconfigroomname, &CC->user, USERCONFIGROOM); + long new_msgnum = quickie_message("Citadel", NULL, NULL, userconfigroomname, ChrPtr(NewProfile), FMT_RFC822, "Profile submitted with EBIO command"); + FreeStrBuf(&NewProfile); + CtdlGetUserLock(&CC->user, CC->curr_user); + CC->user.msgnum_bio = new_msgnum; + CtdlPutUserLock(&CC->user); + if (old_msgnum > 0) { + syslog(LOG_DEBUG, "Deleting old message %ld from %s", old_msgnum, userconfigroomname); + CtdlDeleteMessages(userconfigroomname, &old_msgnum, 1, ""); } - fclose(fp); } + /* - * read user bio + * Command to read user bio (profile) in plain text. + * This is deprecated , or at least it will be when its replacement is written :) + * I want commands to get/set bio in full MIME wonderfulness. */ void cmd_rbio(char *cmdbuf) { struct ctdluser ruser; - char buf[256]; - FILE *fp; + char buf[SIZ]; extract_token(buf, cmdbuf, 0, '|', sizeof buf); if (CtdlGetUser(&ruser, buf) != 0) { cprintf("%d No such user.\n",ERROR + NO_SUCH_USER); return; } - snprintf(buf, sizeof buf, "%s%ld",ctdl_bio_dir,ruser.usernum); - + cprintf("%d OK|%s|%ld|%d|%ld|%ld|%ld\n", LISTING_FOLLOWS, ruser.fullname, ruser.usernum, ruser.axlevel, (long)ruser.lastcall, ruser.timescalled, ruser.posted); - fp = fopen(buf,"r"); - if (fp == NULL) - cprintf("%s has no bio on file.\n", ruser.fullname); - else { - while (fgets(buf, sizeof buf, fp) != NULL) cprintf("%s",buf); - fclose(fp); + + struct CtdlMessage *msg = CtdlFetchMessage(ruser.msgnum_bio, 1); + if (msg != NULL) { + CtdlOutputPreLoadedMsg(msg, MT_CITADEL, HEADERS_NONE, 0, 0, 0); + CM_Free(msg); } cprintf("000\n"); } + +/* + * Import function called by import_old_bio_files() for a single user + */ +void import_one_bio_file(char *username, long usernum, char *path) +{ + syslog(LOG_DEBUG, "Import legacy bio for %s, usernum=%ld, filename=%s", username, usernum, path); + + FILE *fp = fopen(path, "r"); + if (!fp) return; + + fseek(fp, 0, SEEK_END); + long data_length = ftell(fp); + + if (data_length >= 1) { + rewind(fp); + char *unencoded_data = malloc(data_length); + if (unencoded_data) { + fread(unencoded_data, data_length, 1, fp); + char *encoded_data = malloc((data_length * 2) + 100); + if (encoded_data) { + sprintf(encoded_data, "Content-type: text/plain; charset=UTF-8\nContent-transfer-encoding: base64\n\n"); + CtdlEncodeBase64(&encoded_data[strlen(encoded_data)], unencoded_data, data_length, 1); + + char userconfigroomname[ROOMNAMELEN]; + struct ctdluser usbuf; + + if (CtdlGetUser(&usbuf, username) == 0) { // no need to lock it , we are still initializing + long old_msgnum = usbuf.msgnum_bio; + CtdlMailboxName(userconfigroomname, sizeof userconfigroomname, &usbuf, USERCONFIGROOM); + long new_msgnum = quickie_message("Citadel", NULL, NULL, userconfigroomname, encoded_data, FMT_RFC822, "Profile imported from bio"); + syslog(LOG_DEBUG, "Message %ld is now the profile for %s", new_msgnum, username); + usbuf.msgnum_bio = new_msgnum; + CtdlPutUser(&usbuf); + unlink(path); // delete the old file , it's in the database now + if (old_msgnum > 0) { + syslog(LOG_DEBUG, "Deleting old message %ld from %s", old_msgnum, userconfigroomname); + CtdlDeleteMessages(userconfigroomname, &old_msgnum, 1, ""); + } + } + free(encoded_data); + } + free(unencoded_data); + } + } + fclose(fp); +} + + /* - * list of users who have entered bios + * Look for old-format "bio" files and import them into the message base */ -void cmd_lbio(char *cmdbuf) { - char buf[256]; - FILE *ls; +void import_old_bio_files(void) +{ + DIR *filedir = NULL; + struct dirent *filedir_entry; + size_t d_namelen; struct ctdluser usbuf; - char listbios[256]; + long usernum = 0; + int d_type = 0; + struct stat s; + char path[PATH_MAX]; - snprintf(listbios, sizeof(listbios),"cd %s; ls",ctdl_bio_dir); - ls = popen(listbios, "r"); - if (ls == NULL) { - cprintf("%d Cannot open listing.\n", ERROR + FILE_NOT_FOUND); + + syslog(LOG_DEBUG, "Importing old style bio files into the message base"); + filedir = opendir("bio"); + if (filedir == NULL) { return; } - - cprintf("%d\n", LISTING_FOLLOWS); - while (fgets(buf, sizeof buf, ls)!=NULL) - if (CtdlGetUserByNumber(&usbuf,atol(buf))==0) - cprintf("%s\n", usbuf.fullname); - pclose(ls); - cprintf("000\n"); + while ( (filedir_entry = readdir(filedir)) , (filedir_entry != NULL)) + { +#ifdef _DIRENT_HAVE_D_NAMLEN + d_namelen = filedir_entry->d_namlen; + +#else + d_namelen = strlen(filedir_entry->d_name); +#endif + +#ifdef _DIRENT_HAVE_D_TYPE + d_type = filedir_entry->d_type; +#else + +#ifndef DT_UNKNOWN +#define DT_UNKNOWN 0 +#define DT_DIR 4 +#define DT_REG 8 +#define DT_LNK 10 + +#define IFTODT(mode) (((mode) & 0170000) >> 12) +#define DTTOIF(dirtype) ((dirtype) << 12) +#endif + d_type = DT_UNKNOWN; +#endif + if ((d_namelen == 1) && + (filedir_entry->d_name[0] == '.')) + continue; + + if ((d_namelen == 2) && + (filedir_entry->d_name[0] == '.') && + (filedir_entry->d_name[1] == '.')) + continue; + + snprintf(path, PATH_MAX, "bio/%s", filedir_entry->d_name); + if (d_type == DT_UNKNOWN) { + if (lstat(path, &s) == 0) { + d_type = IFTODT(s.st_mode); + } + } + switch (d_type) + { + case DT_DIR: + break; + case DT_LNK: + case DT_REG: + usernum = atol(filedir_entry->d_name); + if (CtdlGetUserByNumber(&usbuf, usernum) == 0) { + import_one_bio_file(usbuf.fullname, usernum, path); + } + } + } + closedir(filedir); + rmdir("bio"); } - CTDL_MODULE_INIT(bio) { if (!threading) { + import_old_bio_files(); CtdlRegisterProtoHook(cmd_ebio, "EBIO", "Enter your bio"); CtdlRegisterProtoHook(cmd_rbio, "RBIO", "Read a user's bio"); - CtdlRegisterProtoHook(cmd_lbio, "LBIO", "List users with bios"); } - /* return our Subversion id for the Log */ + /* return our module name for the log */ return "bio"; } - -