X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fbio%2Fserv_bio.c;h=1c03c480546a6927e4e703f40219ea0d5a205faf;hb=4f16550e3fe10c62b691b3976ff8b4fccc9dd830;hp=81a54b573914d230981ad2c063e5571ffff9f2b5;hpb=0475c981817d12900332693297a77a9ae7168129;p=citadel.git diff --git a/citadel/modules/bio/serv_bio.c b/citadel/modules/bio/serv_bio.c index 81a54b573..1c03c4805 100644 --- a/citadel/modules/bio/serv_bio.c +++ b/citadel/modules/bio/serv_bio.c @@ -2,7 +2,7 @@ * This module implementsserver commands related to the display and * manipulation of user "bio" files. * - * Copyright (c) 1987-2015 by the citadel.org team + * Copyright (c) 1987-2017 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 @@ -24,94 +24,149 @@ /* - * 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) < CtdlGetConfigLong("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, 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) +void import_old_bio_files(void) { DIR *filedir = NULL; struct dirent *filedir_entry; struct dirent *d; - int dont_resolve_uids; size_t d_namelen; struct ctdluser usbuf; + long usernum = 0; int d_type = 0; + struct stat s; + char path[PATH_MAX]; + syslog(LOG_DEBUG, "Importing old style bio files into the message base"); d = (struct dirent *)malloc(offsetof(struct dirent, d_name) + PATH_MAX + 2); if (d == NULL) { - cprintf("%d Cannot open listing.\n", ERROR + FILE_NOT_FOUND); return; } filedir = opendir (ctdl_bio_dir); if (filedir == NULL) { free(d); - cprintf("%d Cannot open listing.\n", ERROR + FILE_NOT_FOUND); return; } - dont_resolve_uids = *cmdbuf == '1'; - cprintf("%d\n", LISTING_FOLLOWS); - while ((readdir_r(filedir, d, &filedir_entry) == 0) && - (filedir_entry != NULL)) + while ( (filedir_entry = readdir(filedir)) , (filedir_entry != NULL)) { #ifdef _DIRENT_HAVE_D_NAMLEN d_namelen = filedir_entry->d_namlen; @@ -144,11 +199,8 @@ void cmd_lbio(char *cmdbuf) (filedir_entry->d_name[1] == '.')) continue; + snprintf(path, PATH_MAX, "%s/%s", ctdl_bio_dir, filedir_entry->d_name); if (d_type == DT_UNKNOWN) { - struct stat s; - char path[PATH_MAX]; - snprintf(path, PATH_MAX, "%s/%s", - ctdl_bio_dir, filedir_entry->d_name); if (lstat(path, &s) == 0) { d_type = IFTODT(s.st_mode); } @@ -159,19 +211,15 @@ void cmd_lbio(char *cmdbuf) break; case DT_LNK: case DT_REG: - if (dont_resolve_uids) { - filedir_entry->d_name[d_namelen++] = '\n'; - filedir_entry->d_name[d_namelen] = '\0'; - client_write(filedir_entry->d_name, d_namelen); + usernum = atol(filedir_entry->d_name); + if (CtdlGetUserByNumber(&usbuf, usernum) == 0) { + import_one_bio_file(usbuf.fullname, usernum, path); } - else if (CtdlGetUserByNumber(&usbuf,atol(filedir_entry->d_name))==0) - cprintf("%s\n", usbuf.fullname); } } free(d); closedir(filedir); - cprintf("000\n"); - + rmdir(ctdl_bio_dir); } @@ -180,12 +228,10 @@ 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 module name for the log */ return "bio"; } - -