int cddbd_submit(FILE *fp, email_hdr_t *eh, int flags, char *errstr) { int i; int len; int ret; int dbflags; db_t *db; char buf[CDDBBUFSIZ]; char buf2[CDDBBUFSIZ]; struct stat sbuf; /* Set the interface type. */ interface = IF_SUBMIT; if(!(flags & MF_TEST)) hperm = *ck_host_perms(interface); if((ret = validate_email(fp, eh, errstr)) != EE_OK) return ret; if(!WRITE_OK(hperm) && !(flags & MF_TEST)) { cddbd_snprintf(errstr, CDDBBUFSIZ, "Email submissions disallowed"); return EE_ERROR; } if(categ_index(eh->eh_category) < 0) { cddbd_snprintf(errstr, CDDBBUFSIZ, "Invalid DB category: %s\n" "Valid categories are:", eh->eh_category); for(i = 0, len = strlen(errstr); categlist[i] != 0; i++) { cddbd_snprintf(&errstr[len], (CDDBBUFSIZ - len), " %s", categlist[i]); len += strlen(categlist[i]) + 1; } return EE_ERROR; } /* Specify acceptable charsets. */ dbflags = charsets[eh->eh_charset].df_flags; if((dbflags & DF_ENC_LATIN1) && utf_as_iso == UAI_CONVERT) dbflags |= DF_ENC_UTF8; if(!(flags & MF_TEST)) dbflags |= DF_CK_SUBMIT; rewind(fp); db = db_read(fp, buf, (DF_MAIL | DF_SUBMITTER | dbflags)); if(db == 0) { cddbd_snprintf(errstr, CDDBBUFSIZ, "Invalid DB submission: %s", buf); return EE_ERROR; } /* Check and disambiguate charset. */ if (db_disam_charset(db)) { cddbd_snprintf(errstr, CDDBBUFSIZ, "Entry rejected: looks like UTF-8."); return EE_ERROR; } if(!(flags & MF_TEST)) { /* Check for postdir, and create if it doesn't exist. */ if(stat(postdir, &sbuf)) { if(mkdir(postdir, (mode_t)db_dir_mode)) { cddbd_log(LOG_ERR, "Failed to create post dir %s.", postdir); cddbd_snprintf(errstr, CDDBBUFSIZ, "Internal server file error"); return EE_ERROR; } (void)cddbd_fix_file(postdir, db_dir_mode, db_uid, db_gid); } else if(!S_ISDIR(sbuf.st_mode)) { cddbd_log(LOG_ERR, "%s is not a directory.", postdir); cddbd_snprintf(errstr, CDDBBUFSIZ, "Internal server file error"); return EE_ERROR; } cddbd_snprintf(buf2, sizeof(buf), "%s/%s", postdir, eh->eh_category); /* zeke - add eh info to db struct for writing to post entry */ db->db_eh.eh_flags = eh->eh_flags; db->db_eh.eh_charset = eh->eh_charset; db->db_eh.eh_encoding = eh->eh_encoding; strcpy (db->db_eh.eh_to, eh->eh_to); strcpy (db->db_eh.eh_rcpt, eh->eh_rcpt); strcpy (db->db_eh.eh_host, eh->eh_host); /* end zeke */ if(!db_post(db, buf2, eh->eh_discid, buf)) { if(db_errno != DE_INVALID) { cddbd_snprintf(errstr, CDDBBUFSIZ, "Internal DB server error: %s", buf); } else cddbd_snprintf(errstr, CDDBBUFSIZ, "Invalid DB file: %s", buf); return EE_ERROR; } cddbd_log(LOG_INFO | LOG_WRITE, "Write (via SMTP - %s): %s %08x", eh->eh_to, eh->eh_category, eh->eh_discid); } else { cddbd_log(LOG_INFO, "Test email submission (from %s): %s %08x", eh->eh_to, eh->eh_category, eh->eh_discid); } return EE_OK; }
int cddbd_email_cmd(FILE *fp, email_hdr_t *eh, int flags, char *errstr) { int ret; int found; pid_t f; char *tcmd; char buf[CDDBCMDLEN]; struct stat sbuf; /* Set the interface type. */ interface = IF_EMAIL; hperm = *ck_host_perms(interface); if(flags & MF_TEST) { cddbd_snprintf(errstr, CDDBBUFSIZ, "Email commands not accepted at this address"); return EE_ERROR; } if((ret = validate_email(fp, eh, errstr)) != EE_OK) return ret; found = 0; rewind(fp); while(fgets(buf, sizeof(buf), fp)) if(!strncmp(buf, asy_prefix[0], strlen(asy_prefix[0]))) { found++; break; } if(!found) { cddbd_snprintf(errstr, CDDBBUFSIZ, "No CDDBP command found in mail body"); return EE_ERROR; } /* Create a temporary file for the mail. */ tcmd = cddbd_mktemp(); if((fp = fopen(tcmd, "w+")) == NULL) { cddbd_snprintf(errstr, CDDBBUFSIZ, "Internal server error: can't open temp file %s", tcmd); return EE_ERROR; } f = cddbd_fork(); /* We're the child. Do the command. */ if(f == 0) { dup2(fileno(fp), 1); dup2(fileno(fp), 2); fclose(fp); close(0); _quit(cddbd_async_command(buf, 0), 0); } if(f < 0) { cddbd_snprintf(errstr, CDDBBUFSIZ, "Internal server error: can't fork"); fclose(fp); cddbd_freetemp(tcmd); return EE_ERROR; } if(wait(0) == -1 && errno != ECHILD) { cddbd_snprintf(errstr, CDDBBUFSIZ, "Internal server error: failed to wait on child (%d)", errno); fclose(fp); cddbd_freetemp(tcmd); return EE_ERROR; } if(stat(tcmd, &sbuf)) { cddbd_snprintf(errstr, CDDBBUFSIZ, "Internal server error: can't stat output file %s (%d)", tcmd, errno); fclose(fp); cddbd_freetemp(tcmd); return EE_ERROR; } /* Put something in the file if it's empty. */ if(sbuf.st_size == 0) { fprintf(fp, "403 Server error.\n"); fflush(fp); } ret = return_mail(fp, eh, (flags | MF_ENC), errstr); if(ret != EE_OK) { cddbd_snprintf(errstr, CDDBBUFSIZ, "Internal server error: can't generate response mail"); } fclose(fp); cddbd_freetemp(tcmd); /* Reset the interface type so we don't log a second hello. */ interface = IF_SUBMIT; return ret; }
/* * Set the user attributes */ void set_attributes(UR_OBJECT user) { char name[USER_NAME_LEN + 1], *recname; int i, tmp; if (word_count < 2) { i = -1; } else { /* FIXME: Add abbreviated matching like help() does */ for (i = 0; setstr[i].type; ++i) { if (!strcasecmp(setstr[i].type, word[1])) { break; } } if (!setstr[i].type) { i = -1; } } if (i == -1) { write_user(user, "Attributes you can set are:\n\n"); for (i = 0; setstr[i].type; ++i) { vwrite_user(user, "~FC%s~RS : %s\n", setstr[i].type, setstr[i].desc); } write_user(user, "\n"); return; } write_user(user, "\n"); switch (i) { case SETSHOW: show_attributes(user); return; case SETGEND: *word[2] = tolower(*word[2]); if (*word[2] == 'm' || *word[2] == 'f' || *word[2] == 'n') { switch (*word[2]) { case 'm': user->gender = MALE; write_user(user, "Gender set to Male\n"); break; case 'f': user->gender = FEMALE; write_user(user, "Gender set to Female\n"); break; case 'n': user->gender = NEUTER; write_user(user, "Gender set to Unset\n"); break; } check_autopromote(user, 1); return; } write_user(user, "Usage: set gender m|f|n\n"); return; case SETAGE: if (word_count < 3) { write_user(user, "Usage: set age <age>\n"); return; } tmp = atoi(word[2]); if (tmp < 0 || tmp > 200) { write_user(user, "You can only set your age range between 0 (unset) and 200.\n"); return; } user->age = tmp; vwrite_user(user, "Age now set to: %d\n", user->age); return; case SETWRAP: switch (user->wrap) { case 0: user->wrap = 1; write_user(user, "Word wrap now ON\n"); break; case 1: user->wrap = 0; write_user(user, "Word wrap now OFF\n"); break; } return; case SETEMAIL: strcpy(word[2], colour_com_strip(word[2])); if (strlen(word[2]) > 80) { write_user(user, "The maximum email length you can have is 80 characters.\n"); return; } if (!validate_email(word[2])) { write_user(user, "That email address format is incorrect. Correct format: [email protected]\n"); return; } strcpy(user->email, word[2]); if (!*user->email) { write_user(user, "Email set to : ~FRunset\n"); } else { vwrite_user(user, "Email set to : ~FC%s\n", user->email); } set_forward_email(user); return; case SETHOMEP: strcpy(word[2], colour_com_strip(word[2])); if (strlen(word[2]) > 80) { write_user(user, "The maximum homepage length you can have is 80 characters.\n"); return; } strcpy(user->homepage, word[2]); if (!*user->homepage) { write_user(user, "Homepage set to : ~FRunset\n"); } else { vwrite_user(user, "Homepage set to : ~FC%s\n", user->homepage); } return; case SETHIDEEMAIL: switch (user->hideemail) { case 0: user->hideemail = 1; write_user(user, "Email now showing to only the admins.\n"); break; case 1: user->hideemail = 0; write_user(user, "Email now showing to everyone.\n"); break; } return; case SETCOLOUR: switch (user->colour) { case 0: user->colour = 1; write_user(user, "~FCColour now on\n"); break; case 1: user->colour = 0; write_user(user, "Colour now off\n"); break; } return; case SETPAGER: if (word_count < 3) { write_user(user, "Usage: set pager <length>\n"); return; } user->pager = atoi(word[2]); if (user->pager < MAX_LINES || user->pager > 99) { vwrite_user(user, "Pager can only be set between %d and 99 - setting to default\n", MAX_LINES); user->pager = 23; } vwrite_user(user, "Pager length now set to: %d\n", user->pager); return; case SETROOM: switch (user->lroom) { case 0: user->lroom = 1; write_user(user, "You will log on into the room you left from.\n"); break; case 1: user->lroom = 0; write_user(user, "You will log on into the main room.\n"); break; } return; case SETFWD: if (!*user->email) { write_user(user, "You have not yet set your email address - autofwd cannot be used until you do.\n"); return; } if (!user->mail_verified) { write_user(user, "You have not yet verified your email - autofwd cannot be used until you do.\n"); return; } switch (user->autofwd) { case 0: user->autofwd = 1; write_user(user, "You will also receive smails via email.\n"); break; case 1: user->autofwd = 0; write_user(user, "You will no longer receive smails via email.\n"); break; } return; case SETPASSWD: switch (user->show_pass) { case 0: user->show_pass = 1; write_user(user, "You will now see your password when entering it at login.\n"); break; case 1: user->show_pass = 0; write_user(user, "You will no longer see your password when entering it at login.\n"); break; } return; case SETRDESC: switch (user->show_rdesc) { case 0: user->show_rdesc = 1; write_user(user, "You will now see the room descriptions.\n"); break; case 1: user->show_rdesc = 0; write_user(user, "You will no longer see the room descriptions.\n"); break; } return; case SETCOMMAND: switch (user->cmd_type) { case 0: user->cmd_type = 1; write_user(user, "You will now see commands listed by functionality.\n"); break; case 1: user->cmd_type = 0; write_user(user, "You will now see commands listed by level.\n"); break; } return; case SETRECAP: if (!amsys->allow_recaps) { write_user(user, "Sorry, names cannot be recapped at this present time.\n"); return; } if (word_count < 3) { write_user(user, "Usage: set recap <name as you would like it>\n"); return; } if (strlen(word[2]) > RECAP_NAME_LEN - 3) { write_user(user, "The recapped name length is too long - try using fewer colour codes.\n"); return; } recname = colour_com_strip(word[2]); if (strlen(recname) > USER_NAME_LEN) { write_user(user, "The recapped name still has to match your proper name.\n"); return; } strcpy(name, recname); strtolower(name); *name = toupper(*name); if (strcmp(user->name, name)) { write_user(user, "The recapped name still has to match your proper name.\n"); return; } strcpy(user->recap, word[2]); strcat(user->recap, "~RS"); /* user->recap is allways escaped with a reset to its colours... */ strcpy(user->bw_recap, recname); vwrite_user(user, "Your name will now appear as \"%s~RS\" on the \"who\", \"examine\", tells, etc.\n", user->recap); return; case SETICQ: strcpy(word[2], colour_com_strip(word[2])); if (strlen(word[2]) > ICQ_LEN) { vwrite_user(user, "The maximum ICQ UIN length you can have is %d characters.\n", ICQ_LEN); return; } strcpy(user->icq, word[2]); if (!*user->icq) { write_user(user, "ICQ number set to : ~FRunset\n"); } else { vwrite_user(user, "ICQ number set to : ~FC%s\n", user->icq); } return; case SETALERT: switch (user->alert) { case 0: user->alert = 1; write_user(user, "You will now be alerted if anyone on your friends list logs on.\n"); break; case 1: user->alert = 0; write_user(user, "You will no longer be alerted if anyone on your friends list logs on.\n"); break; } return; case SETREVBUF: switch (user->reverse_buffer) { case 0: user->reverse_buffer = 1; write_user(user, "~FCBuffers are now reversed\n"); break; case 1: user->reverse_buffer = 0; write_user(user, "Buffers now not reversed\n"); break; } return; } }