This is menue.c in view mode; [Download] [Up]
/* $Id: menue.c,v 1.2 1995/12/19 19:30:47 eilts Exp eilts $ */ #include "bbs.h" int getcmdline_c(char cmdline[], const menuetyp startmenue[], const menuetyp sysmenue[], const menuetyp bbsmenue[], const chrootrecordtyp *chrootrecord, confrecordtyp *confrecord) { int arganz, lang; static boolean insysmenue = FALSE; static boolean inbbsmenue = FALSE; static boolean inreader = FALSE; char key; static char nextkey=NO_KEY; SIGSET_T sigset; sendstatustodaemon(BBS_IDLE,confrecord); setsighandler(SIGUSR1, sigtalkaccepthandler); sigemptyset(&sigset); sigaddset(&sigset, SIGUSR1); sigprocmask(SIG_UNBLOCK,&sigset,NULL); lang = confrecord->userrecord.lang; noecho(); crmode(); arganz = -1; cmdline[0] = '\0'; if (insysmenue) { key = SYS_KEY; } else if (inbbsmenue) { key = BBS_KEY; } else { key = selectmenue_c(cmdline, startmenue, msg("getcmdline_c",0,lang), nextkey, "", confrecord); } sigaddset(&sigset, SIGUSR2); sigprocmask(SIG_BLOCK,&sigset,NULL); sendstatustodaemon(BBS_BUSY,confrecord); nextkey = NO_KEY; switch (key) { case HELP_KEY: arganz = 0; break; case DOC_KEY: arganz = 0; break; case SYS_KEY: insysmenue = TRUE; key = selectmenue_c(cmdline, sysmenue, msg("getcmdline_c",1,lang), NO_KEY, "", confrecord); switch (key) { case ENV_KEY: arganz = 0; break; case LANG_KEY: arganz = sprache_c(cmdline, confrecord); break; case PROT_KEY: arganz = protokoll_c(cmdline, confrecord); break; case AUTOZ_KEY: arganz = autozmodem_c(cmdline, confrecord); break; case FULLIST_KEY: arganz = fullist_c(cmdline, confrecord); break; case TERM_KEY: arganz = term_c(cmdline, confrecord); break; case PASSWD_KEY: arganz = newpasswd_c(cmdline, confrecord); break; case QUIT_KEY: case ESCAPE_KEY: insysmenue = FALSE; break; } break; case DIR_KEY: arganz = 0; break; case CD_KEY: arganz = selectdir_c(cmdline, chrootrecord, "cd", confrecord); if (arganz >= 0) { nextkey = CD_KEY; } else { writetouser(confrecord,msg("getcmdline_c",3,lang),chrootrecord->cwdname); } break; case PWD_KEY: arganz = 0; break; case SHOW_KEY: arganz = selectfiles_c(cmdline, 0, "show", confrecord); if (arganz < 1) cmdline[0] = '\0'; break; case DOWNLOAD_KEY: arganz = selectfiles_c(cmdline, MAXARGS, "get", confrecord); if (arganz < 1) cmdline[0] = '\0'; break; case UPLOAD_KEY: arganz = put_c(cmdline, confrecord); break; case AUTOZDETECTED: arganz = 0; break; case BBS_KEY: inbbsmenue = TRUE; key = selectmenue_c(cmdline, bbsmenue, msg("getcmdline_c",2,lang), inreader?MSGBROWSE_KEY:NO_KEY, "", confrecord); switch (key) { case TALK_KEY: arganz = talk_c(cmdline, confrecord); break; case SYSOPMAIL_KEY: arganz = sendmail_c(cmdline, NULL, NULL, NULL, TRUE, chrootrecord, confrecord); if (arganz < 2) cmdline[0] = '\0'; break; case EMAIL_KEY: arganz = sendmail_c(cmdline, NULL, NULL, NULL, FALSE, chrootrecord, confrecord); if (arganz < 2) cmdline[0] = '\0'; break; case MESSAGE_KEY: arganz = sendmessage_c(cmdline, NULL, NULL, NULL, chrootrecord, confrecord); if (arganz < 2) cmdline[0] = '\0'; break; case MSGBROWSE_KEY: inreader = TRUE; arganz = msgbrowser_c(cmdline, bbsmenue, chrootrecord, confrecord); if (arganz < 1) { inreader = FALSE; cmdline[0] = '\0'; } break; #ifdef NNTPNEWS case NEWSBROWSE_KEY: arganz = newsbrowser_c(confrecord); cmdline[0] = '\0'; break; case NEWSPOST_KEY: arganz = postarticle_c(NULL, NULL, NULL, NULL, NULL, confrecord); cmdline[0] = '\0'; break; case NEWSSUBSCR_KEY: arganz = subscribenewsgroups_c(confrecord); cmdline[0] = '\0'; break; #endif case QUIT_KEY: case ESCAPE_KEY: inbbsmenue = FALSE; break; } break; case QUIT_KEY: arganz = bbsquit_c(cmdline, confrecord); break; default: cmdline[0] = '\0'; } return arganz; } char selectmenue_c(char cmd[], const menuetyp menue[], const char *kopfstr, const char nextkey, const char *helpcontext, const confrecordtyp *confrecord) { int lang, z, k; char c, key, cset[100]; if (nextkey == NO_KEY) { lang = confrecord->userrecord.lang; for (k=0, z=0; (c=menue[k].key)!='\0'; k++) { if (*(menue[k].dec) != '\0') cset[z++] = c; } cset[z] = '\0'; clear(); move(0, (COLS - strlen(kopfstr)) / 2); addstr(kopfstr); for (k=0,z=2; (c=menue[k].key)!='\0'; k++,z++) { if (c == ' ') continue; move(z,10); addch('['); standout(); addch(c); standend(); addch(']'); move(z,16); addstr(menue[k].dec[lang]); } key = getkeyonprompt(msg("selectmenue_c",0,lang), cset, TRUE, TRUE, helpcontext, confrecord); } else { key = nextkey; } if (key == ESCAPE_KEY) return key; if (key == AUTOZDETECTED) { c = UPLOAD_KEY; } else { c = key; } k = 0; while (menue[k].key!='\0') { if (menue[k].key==c && *(menue[k].dec)!='\0') break; k++; } strcpy(cmd,menue[k].cmd); return key; } #ifdef NNTPNEWS int newsbrowser_c(const confrecordtyp *confrecord) { int lang, newsrc_anz, k, n; char key, *bgbuf, *sp, str[STRLEN+1]; boolean sync_newsrc; newsstattyp newsrecord; grouptyp grouprecord; tlistetyp *newsrcliste = (tlistetyp *)0; tlistetyp *artliste = (tlistetyp *)0; lang = confrecord->userrecord.lang; bbslog(LOG_FILE,confrecord,"newsbrowser_c"); if (checknewsperms(confrecord) < 0) { writetouser(confrecord,msg("newsbrowser_c",0,lang)); errormsg(E_LOGFILE,confrecord,"bbs","newsbrowser_c", "no permittion to read news"); return 0; } if (createnewsrcdb(&newsrecord,confrecord) == NULL) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","newsbrowser_c", "cannot create newsrc DB"); return -1; } newsrc_anz = newsrcdbtolist(&newsrcliste,newsrecord.newsrcdb,confrecord); sortliste(newsrcliste,TL_BLOCKLEN,newsrc_anz,confrecord); bgbuf = showmsgline(msg("newsbrowser_c",1,lang),confrecord->nntpserver); if (nntp_connect(&newsrecord,confrecord) < 0) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","newsbrowser_c", "cannot connect to Newsserver %s:",confrecord->nntpserver, newsrecord.lastretstr); removeliste(&newsrcliste,TRUE,TL_BLOCKLEN); newsrecord.newsrcdb->close(newsrecord.newsrcdb); return -1; } *grouprecord.groupname = '\0'; while (TRUE) { sprintf(str,msg("newsbrowser_c",2,lang),newsrc_anz); key = selectpager_c(newsrcliste,newsrc_anz,str,NULL,TRUE, "newsbrowser_grpselect",confrecord); if (key == ESCAPE_KEY) break; for (k=0; k<newsrc_anz; k++) { readliste(&newsrcliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); if (*sp == 'T') break; } if (newsrc_anz == 0 || *sp != 'T') { sp = str; *str = 'F'; if (getnewsgrpname(&str[1],confrecord) == 1) { *str = 'T'; /* key = getkeyonprompt(msg("newsbrowser_c",3,lang),"AU",TRUE,FALSE, NULL,confrecord); if (key == 'A') unread_only = FALSE; */ } } if (*sp == 'T') { *sp = '!'; strcpy(grouprecord.groupname,&sp[1]); browsegroup(&grouprecord,&newsrecord,confrecord); n = lookupnewsrcdb(newsrecord.newsrcdb,grouprecord.groupname,0,NULL,0, confrecord); if (n > 0) { key = getkeyonprompt(msg("newsbrowser_c",4,lang),"JYN",TRUE,FALSE, "newsbrowser_subscribe",confrecord); } if (n == 0 || (n > 0 && key != 'N')) { sync_newsrc = (confrecord->userrecord.seclevel != HIGHSECURITY); updatenewsrc(newsrecord.newsrcdb,&grouprecord,sync_newsrc,confrecord); if (n > 0 && key != 'N') { strcpy(str,"!"); strmaxcat(str,grouprecord.groupname,STRLEN); addstrtoliste(&newsrcliste,TRUE,newsrc_anz++,TL_BLOCKLEN,str, confrecord); } } removeliste(&artliste,TRUE,TL_BLOCKLEN); } } showmsgline("quit newsserver %s ...",confrecord->nntpserver); nntp_close(&newsrecord); removeliste(&newsrcliste,TRUE,TL_BLOCKLEN); newsrecord.newsrcdb->close(newsrecord.newsrcdb); return 0; } int postarticle_c(const char *file, const char *groups, const char *subj, const char *refs, newsstattyp *newsrec, const confrecordtyp *confrecord) { int anz, n, k, lang; char newsgroups[ARG_MAX+1], nstr[ARG_MAX+1], letter[PATH_MAX+1], str[2*STRLEN+2], subject[STRLEN+1], *splits[MAXARGS+1], *sp, *bgbuf, key = '\0'; tlistetyp *tliste = (tlistetyp *)0; lang = confrecord->userrecord.lang; move(0,0); clear(); standout(); addstr(msg("postarticle_c",0,lang)); standend(); if (checknewsperms(confrecord) < 1) { writetouser(confrecord,msg("postarticle_c",1,lang)); errormsg(E_LOGFILE,confrecord,"bbs","postarticle_c", "no permittion to post"); return 0; } move(2,0); addstr(msg("postarticle_c",7,lang)); do { *newsgroups = '\0'; if (groups != NULL) { strmaxcpy(newsgroups,groups,ARG_MAX); anz = splitstring(splits,newsgroups,',',MAXARGS); for (n=0; n < anz; n++) { *str = 'T'; strcpy(&str[1],splits[n]); addstrtoliste(&tliste,TRUE,n,TL_BLOCKLEN,str,confrecord); } key = selectpager_c(tliste,anz,msg("postarticle_c",0,lang),NULL,FALSE, NULL,confrecord); *newsgroups = '\0'; if (key != ESCAPE_KEY) { for (n=0; n < anz; n++) { readliste(&tliste,FALSE,n,TL_BLOCKLEN,&sp,confrecord); if (*sp == 'T') { strmaxcat(newsgroups,&sp[1],ARG_MAX-1); strcat(newsgroups,","); } } newsgroups[strlen(newsgroups)-1] = '\0'; } removeliste(&tliste,TRUE,TL_BLOCKLEN); move(2,0); clrtobot(); } n = 0; if (key != ESCAPE_KEY) { move(8,0); clrtobot(); addstr(msg("postarticle_c",2,lang)); n = readfromuser(newsgroups,newsgroups,ARG_MAX,TRUE,confrecord); } if (n <= 0) return n; strmaxcpy(nstr,newsgroups,ARG_MAX); anz = splitstring(splits,nstr,',',MAXARGS); for (n=0,k=0; n < anz; n++) { if (checkgroup(splits[n],confrecord) == 0) { k++; errormsg(E_LOGFILE|E_USER,confrecord,"bbs","postarticle_c", msg("postarticle_c",3,lang),splits[n]); } } if (k > 0) { key = getkeyonprompt(msg("postarticle_c",4,lang),"PRAWN",TRUE, FALSE,NULL,confrecord); } else { key = 'P'; } if (key == 'A') return 0; } while (key != 'P' && key != 'W'); move(10,0); addstr(msg("postarticle_c",5,lang)); if (readfromuser(subject,subj,STRLEN,TRUE,confrecord) == 0) { return 0; } if (file == NULL) { scratchfilename(letter,"post-",NULL,confrecord->scratchdir); } else { strcpy(letter,file); } n = edit(letter,0600,FALSE,0,confrecord); if (n == 0) { bgbuf = showmsgline(msg("postarticle_c",6,lang)); if (*confrecord->nntppost == 'Y' || *confrecord->nntppost == 'y') { n = do_postart_nntp(newsgroups,subject,refs,letter,newsrec,confrecord); } else { n = do_postart_inews(newsgroups,subject,refs,letter,confrecord); } } else if (n > 0) { unlink(letter); return 0; } return n; } int subscribenewsgroups_c(const confrecordtyp *confrecord) { int k, n, anz, lang; char key, str[2*STRLEN+3], *sp, *bgbuf; boolean oldgroup, err = FALSE; DBASE_DB *newsrcdb; DBASE_DBT dbkey, dbdata; newsstattyp newsrecord; tlistetyp *tliste = (tlistetyp *)0; lang = confrecord->userrecord.lang; move(0,0); clear(); standout(); addstr(msg("subscribenewsgroups_c",0,lang)); standend(); if (checknewsperms(confrecord) < 0 || confrecord->userrecord.seclevel == HIGHSECURITY) { writetouser(confrecord,msg("subscribenewsgroups_c",1,lang)); errormsg(E_LOGFILE,confrecord,"bbs","subscribenewsgroups_c", "no permittion to subscribe news"); return 0; } if (createnewsrcdb(&newsrecord,confrecord) == NULL) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","subscribenewsgroups_c", "cannot create newsrc DB"); return -1; } newsrcdb = newsrecord.newsrcdb; bgbuf = showmsgline(msg("subscribenewsgroups_c",2,lang)); if ((anz=getallnewsgroups(&tliste,GROUPNAME_MASK,confrecord)) < 0) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","subscribenewsgroups_c", "cannot get list of all newsgroups"); newsrcdb->close(newsrcdb); return -1; } /* removemsgline(bgbuf); */ sortliste(tliste,TL_BLOCKLEN,anz,confrecord); for (k=0; k<anz; k++) { readliste(&tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); if (lookupnewsrcdb(newsrcdb,sp,0,NULL,0,confrecord) == 0) { *str = 'T'; } else { *str = 'F'; } strcpy(&str[1],sp); addstrtoliste(&tliste,TRUE,k,TL_BLOCKLEN,str,confrecord); } key = selectpager_c(tliste,anz,msg("subscribenewsgroups_c",0,lang), NULL,FALSE,"subscribenewsgroups",confrecord); if (selectpagerquit_c(key) > 0) { for (k=0; k<anz; k++) { readliste(&tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); oldgroup = (lookupnewsrcdb(newsrcdb,&sp[1],0,NULL,0,confrecord) == 0); if (*sp == 'F' && oldgroup) { DBASE_SIZE(dbkey) = strlen(&sp[1]) + 1; DBASE_DATA(dbkey) = &sp[1]; n = newsrcdb->del(newsrcdb,&dbkey,0); if (n > 0) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","subscribenewsgroups_c", "no entry %s in newsrc DB",&sp[1]); } else if (n < 0) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","subscribenewsgroups_c", "cannot delete newsrc DB entry %s: %m",&sp[1]); err = TRUE; } } else if (*sp == 'T' && ! oldgroup) { DBASE_SIZE(dbkey) = strlen(&sp[1]) + 1; DBASE_DATA(dbkey) = &sp[1]; DBASE_SIZE(dbdata) = 1; DBASE_DATA(dbdata) = ""; n = newsrcdb->put(newsrcdb,&dbkey,&dbdata,R_NOOVERWRITE); if (n > 0) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","subscribenewsgroups_c", "duplicaty key %s in newsrc DB", &sp[1]); } else if (n < 0) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","subscribenewsgroups_c", "cannot add key %s to newsrc DB: %m",&sp[1]); err = TRUE; } } } removeliste(&tliste,TRUE,TL_BLOCKLEN); if (err) { newsrcdb->close(newsrcdb); return -1; } anz = newsrcdbtolist(&tliste,newsrcdb,confrecord); if (anz < 0 || syncnewsrcdb(newsrcdb,confrecord) < 0) { anz = -1; errormsg(E_LOGFILE|E_USER,confrecord,"bbs","subscribenewsgroups_c", "saving newsrc failed"); } removeliste(&tliste,TRUE,TL_BLOCKLEN); } newsrcdb->close(newsrcdb); return anz; } char newspager_c(tlistetyp *tliste, const int anz, const char *header, const char *subheader, const boolean hotselect, const char *helpcontext, const confrecordtyp *confrecord) { int kopfzeilen, lines, zstep, offset, ypos, kmax, k, n; char *zary[MAXMEN], key; clear(); move(0,0); standout(); addstr(header); standend(); if (subheader != (char *)0) { kopfzeilen = 3; move(1,0); addstr(subheader); } else { kopfzeilen = 2; } lines = confrecord->userrecord.lines - kopfzeilen -1; if (lines > MAXMEN) lines = MAXMEN; zstep = lines - 2; offset = 0; do { move(kopfzeilen,0); clrtobot(); kmax = offset+lines > anz ? anz : offset+lines; for (k=offset,n=0; k<kmax; k++,n++) { ypos = kopfzeilen + k - offset; readliste(&tliste,FALSE,k,TL_BLOCKLEN,&(zary[n]),confrecord); if (*zary[n]!='X') { move(ypos,2); addch('['); standout(); addch('A'+k-offset); standend(); addch(']'); } move(ypos,6); addstr_withmargin(&(zary[n][1])); } if (anz > lines) { if (offset+lines < anz) { n = offset +1; } else { n = 0; } } else { n = -1; } key = menueselect_c(zary,kmax-offset,n,kopfzeilen,hotselect,helpcontext, confrecord); if (key == ALLQUANTOR_KEY) { newsdateselect_c(tliste,anz,confrecord); } if (pagerstep(key) < 0) { offset -= zstep; } else if (pagerstep(key) > 0) { offset += zstep; } if (offset > anz-lines) offset = anz-lines; if (offset < 0) offset = 0; } while (selectpagerquit_c(key) == 0); return key; } int newsdateselect_c(tlistetyp *tliste, const int anz, const confrecordtyp *confrecord) { int fromtime, totime, isttime, year, k, n, lang; char str[S_STRLEN+1], sstr[S_STRLEN+1], *sp, *splits[5], c; lang = confrecord->userrecord.lang; move(LINES-1,0); clrtoeol(); standout(); addstr(msg("newsdateselect_c",0,lang)); standend(); refresh(); c = bbsgetch(TRUE); if (c == '?') { writetouser(confrecord,msg("newsdateselect_c",1,lang)); refresh(); c = bbsgetch(TRUE); } if (c == ESCAPE_KEY || c == RETURN_KEY || c == NEWLINE_KEY) { return(0); } else { str[0] = c; str[1] = '\0'; if (readfromuser(str,str,S_STRLEN,TRUE,confrecord) == 0) return 0; } for (k=0; str[k] && str[k]!='-' && k<S_STRLEN; k++) sstr[k] = str[k]; sstr[k] = '\0'; n = splitstring(splits,sstr,'.',4); if (n == 2) { sp = gettime(); year = atoi(&sp[20]); } else if (n == 3) { year = atoi(splits[2]); if (year > 90 && year < 1900) { year += 1900; } else if (year < 2000) { year += 2000; } } else { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","newsdateselect_c", msg("newsdateselect_c",2,lang)); return -1; } fromtime = atoi(splits[0]) + 31 * (atoi(splits[1]) + 12 * year); if ((sp=strchr(str,'-')) != NULL) { sp++; strcpy(sstr,sp); n = splitstring(splits,sstr,'.',4); if (n == 2) { /* */ } else if (n == 3) { year = atoi(splits[2]); if (year > 90 && year < 1900) { year += 1900; } else if (year < 2000) { year += 2000; } } else { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","newsdateselect_c", msg("newsdateselect_c",2,lang)); return -1; } totime = atoi(splits[0]) + 31 * (atoi(splits[1]) + 12 * year); } else { totime = 0; } for (k=0; k < anz; k++) { readliste(&tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); isttime = getdatenum(splittoken(sp,'\n',3)); if (isttime < 0) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","newsdateselect_c", "%s: unknown month",splits[1]); continue; } if (isttime >= fromtime && (totime == 0 || isttime <= totime)) { *sp = (*sp == 'T') ? 'F' : 'T'; } } return 0; } #endif int msgbrowser_c(char cmd[], const menuetyp bbsmenue[], const chrootrecordtyp *chrootrecord, const confrecordtyp *confrecord) { int lang, n, k, nr, anz; char *sp, *splits[MAXARGS+1], key, zeile[2*STRLEN+6], addr[STRLEN+1], realname[STRLEN+1]; boolean corrupthdr = FALSE; static boolean firstcall = TRUE; tlistetyp *tliste = (tlistetyp *)0, *idliste = (tlistetyp *)0; lang = confrecord->userrecord.lang; anz = listmessages(&tliste,confrecord); if (anz == 0) { if (firstcall) writetouser(confrecord,msg("msgbrowser_c",0,lang)); firstcall = FALSE; return 0; } for (k=0; k<anz; k++) { readliste(&tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); if (splitstring(splits,sp,'\n',3) != 3) { corrupthdr = TRUE; addstrtoliste(&tliste,TRUE,k,TL_BLOCKLEN,"Xcorrupt entry (not readable)", confrecord); addstrtoliste(&idliste,TRUE,k,TL_BLOCKLEN,"",confrecord); } else { switch (addresstyp(splits[0],confrecord)) { case 0: key = 'M'; break; case 1: key = 'S'; break; case 2: key = 'L'; break; case 3: key = 'R'; break; default: key = '?'; } parseaddrline(addr,realname,splits[0]); sp = *realname != '\0' ? realname : addr; sprintf(zeile,"F%s (%c): %s",sp,key,splits[1]); addstrtoliste(&tliste,TRUE,k,TL_BLOCKLEN,zeile,confrecord); addstrtoliste(&idliste,TRUE,k,TL_BLOCKLEN,splits[2],confrecord); } } if (corrupthdr && firstcall) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","msgbrowser_c", "some headers are corrupted"); } key = selectpager_c(tliste,anz,msg("msgbrowser_c",1,lang),NULL,TRUE, "msgbrowser_select",confrecord); n = 0; if (key != ESCAPE_KEY) { for (nr=0; nr<anz; nr++) { readliste(&tliste,FALSE,nr,TL_BLOCKLEN,&sp,confrecord); if (*sp == 'T') { key = getkeyonprompt(msg("msgbrowser_c",2,lang),"RDAG",TRUE,FALSE, "msgbrowser_menu",confrecord); readliste(&idliste,FALSE,nr,TL_BLOCKLEN,&sp,confrecord); if (key == 'A') { n = mailreply(cmd,nr,sp,bbsmenue,chrootrecord,confrecord); } else { strcpy(zeile,cmd); sprintf(cmd,"%s -a %c -n %d -i %s",zeile,key,nr,sp); n = 2; } break; } } } removeliste(&tliste,TRUE,TL_BLOCKLEN); removeliste(&idliste,TRUE,TL_BLOCKLEN); return n; } int sendmessage_c(char cmd[], const char *file, const char *addr, const char *subj, const chrootrecordtyp *chrootrecord, const confrecordtyp *confrecord) { int n, k, anz, lang; char *sp, key, str[STRLEN+1], str2[STRLEN+1], letter[PATH_MAX+1], address[ARG_MAX+1], subject[STRLEN+1], user_l[STRLEN+1], *splits[MAXARGS+1]; tlistetyp *tliste; lang = confrecord->userrecord.lang; if (*(confrecord->userrecord.realname)) { sprintf(user_l,"%s <%s>",confrecord->userrecord.realname, confrecord->userrecord.name); } else { strcpy(user_l,confrecord->userrecord.name); } tliste = (tlistetyp *)0; if ((anz=getallusernames(&tliste,USERNAME_MASK|REALNAME_MASK, confrecord)) < 0) { return -1; } #ifdef NO_MESSAGES_TO_YOURSELF for (k=0; k<anz; k++) { readliste(&tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); if (strcmp(sp,user_l) == 0) { delfromliste(&tliste,TRUE,k,&anz,TL_BLOCKLEN,confrecord); break; } } #endif sortliste(tliste,TL_BLOCKLEN,anz,confrecord); if (addr != NULL) { strmaxcpy(address,addr,ARG_MAX); splitstring(splits,address,',',MAXARGS); for (n=0; splits[n] != NULL; n++) { parseaddrline(str,str2,splits[n]); strcpy(splits[n],str); } } for (k=0; k<anz; k++) { readliste(&tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); *str = 'F'; if (addr != NULL) { for (n=0; splits[n] != NULL; n++) { parseaddrline(str,str2,sp); if (strcmp(splits[n],str) == 0) { *str = 'T'; break; } } } strcpy(&str[1],sp); addstrtoliste(&tliste,TRUE,k,TL_BLOCKLEN,str,confrecord); } key = selectpager_c(tliste,anz,msg("sendmessage_c",0,lang),NULL,FALSE, "sendmessage",confrecord); n = 0; *address = '\0'; if (key != ESCAPE_KEY) { for (k=0; k<anz; k++) { readliste(&tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); if (*sp == 'T') { strmaxcat(address,&sp[1],ARG_MAX-1); strcat(address,","); n++; } } } removeliste(&tliste,TRUE,TL_BLOCKLEN); if (n > 0) { address[strlen(address)-1] = '\0'; clear(); move(2,0); addstr(msg("sendmessage_c",0,lang)); addch(' '); addstr(address); addstr(msg("sendmessage_c",1,lang)); if (readfromuser(subject,subj,STRLEN,TRUE,confrecord) == 0) { return 0; } if (file == NULL) { scratchfilename(letter,"letter-",NULL,confrecord->scratchdir); unlink(letter); } else { strcpy(letter,file); } if (edit(letter,0600,FALSE,0,confrecord) == 0) { strmaxcat(cmd," -l ",ARG_MAX); strmaxcat(cmd,getchrootpath(letter,confrecord->scratchdir),ARG_MAX); n = 2; if (*subject != '\0') { strmaxcat(cmd," -s ",ARG_MAX); strmaxcat(cmd,subject,ARG_MAX); n = 3; } strmaxcat(cmd," -a ",ARG_MAX); strmaxcat(cmd,address,ARG_MAX); if (strlen(cmd) >= ARG_MAX) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","sendmessage_c", "line too long"); return -1; } return n; } else { unlink(letter); n = 0; } } return n; } int sendmail_c(char cmd[], const char *file, const char *addr, const char *subj, const boolean sysopmail, const chrootrecordtyp *chrootrecord, const confrecordtyp *confrecord) { int anz, lang, n; char path[PATH_MAX+1], letter[PATH_MAX+1], address[ARG_MAX+1], str[2*STRLEN+2], subject[STRLEN+1], *splits[MAXARGS+1], *sp, key = '\0'; tlistetyp *tliste = (tlistetyp *)0; lang = confrecord->userrecord.lang; move(0,0); clear(); standout(); addstr(msg("sendmail_c",0,lang)); standend(); addstr(msg("sendmail_c",4,lang)); addstr(msg("sendmail_c",1,lang)); if (sysopmail) { printw("%s (Sysop)",confrecord->sysop); strmaxcpy(address,confrecord->sysop,STRLEN); n = 1; } else { *address = '\0'; if (addr != NULL) { strmaxcpy(address,addr,ARG_MAX); anz = splitstring(splits,address,',',MAXARGS); for (n=0; n < anz; n++) { *str = 'T'; strcpy(&str[1],splits[n]); addstrtoliste(&tliste,TRUE,n,TL_BLOCKLEN,str,confrecord); } key = selectpager_c(tliste,anz,msg("sendmail_c",0,lang),NULL,FALSE, NULL,confrecord); *address = '\0'; if (key != ESCAPE_KEY) { for (n=0; n < anz; n++) { readliste(&tliste,FALSE,n,TL_BLOCKLEN,&sp,confrecord); if (*sp == 'T') { strmaxcat(address,&sp[1],ARG_MAX-1); strcat(address,","); } } address[strlen(address)-1] = '\0'; } removeliste(&tliste,TRUE,TL_BLOCKLEN); move(1,0); clrtobot(); move(2,0); } n = 0; if (key != ESCAPE_KEY) { n = readfromuser(address,address,ARG_MAX,TRUE,confrecord); } if (n > 0) { if ((n=checkmailperms(address,confrecord)) != 0) { writetouser(confrecord,msg("sendmail_c",3,lang)); errormsg(E_LOGFILE,confrecord,"bbs","sendmail_c", "address %s: no permittion (typ %d)",address,n); return 0; } n = 1; } } if (n > 0) { addstr(msg("sendmail_c",2,lang)); if (readfromuser(subject,subj,STRLEN,TRUE,confrecord) == 0) { return 0; } strcpy(path,confrecord->scratchdir); if (file == NULL) { sprintf(letter,"%s/letter.%ld",path,(long)getpid()); } else { strcpy(letter,file); } if (edit(letter,0600,FALSE,0,confrecord) == 0) { strmaxcat(cmd," -l ",ARG_MAX); if (chrootrecord != NULL) { strmaxcat(cmd,getchrootpath(letter,confrecord->scratchdir),ARG_MAX); } else { strmaxcat(cmd,letter,ARG_MAX); } strmaxcat(cmd," -a ",ARG_MAX); strmaxcat(cmd,address,ARG_MAX); n = 2; if (*subject != '\0') { strmaxcat(cmd," -s ",ARG_MAX); strmaxcat(cmd,subject,ARG_MAX); n++; } if (strlen(cmd) >= ARG_MAX) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","sendmail_c", "line too long"); return -1; } return n; } else { unlink(letter); } } return 0; } int talk_c(char cmd[], const confrecordtyp *confrecord) { int k, n, nr, anz, lang; PID_T mypid; char key, str[2*S_STRLEN+1], *params[10], *sp; const char *mp; sessionrecordtyp sessionrecords[MAXSESSIONS]; tlistetyp *tliste; lang = confrecord->userrecord.lang; mypid = getpid(); if ((anz=getsessions(sessionrecords,MAXSESSIONS,confrecord)) < 0) { return(-1); } tliste = (tlistetyp *)0; /* addstrtoliste(&tliste,TRUE,0,TL_BLOCKLEN,"",confrecord); */ n = 0; for (nr=0; nr<anz; nr++) { if (sessionrecords[nr].pid != mypid) { if (sessionrecords[nr].talking_to > 0) { mp = msg("talk_c",0,lang); } else if (sessionrecords[nr].status == BBS_BUSY) { mp= msg("talk_c",1,lang); } else { mp= msg("talk_c",2,lang); } sprintf(str,"F%s (TTY %s, PID %ld) %s",sessionrecords[nr].user, sessionrecords[nr].tty,(long)sessionrecords[nr].pid,mp); addstrtoliste(&tliste,TRUE,n++,TL_BLOCKLEN,str,confrecord); } } anz = n; if (anz > 0) { sortliste(tliste,TL_BLOCKLEN,anz,confrecord); key = selectpager_c(tliste,anz,msg("talk_c",3,confrecord->userrecord.lang), NULL,TRUE,"talk",confrecord); n = 0; if (key != ESCAPE_KEY) { for (k=0; k<anz; k++) { readliste(&tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); if (*sp == 'T') { splitparams(params,sp); strcat(cmd," "); strcat(cmd,params[4]); cmd[strlen(cmd)-1] = '\0'; n++; } } } } else { writetouser(confrecord,msg("talk_c",4,confrecord->userrecord.lang)); n = 0; } removeliste(&tliste,TRUE,TL_BLOCKLEN); return n; } int newpasswd_c(char cmd[], const confrecordtyp *confrecord) { int lang, k=0; char str[PASS_MAX+S_STRLEN+10], username[S_STRLEN+1], newpasswd[PASS_MAX+1]; lang = confrecord->userrecord.lang; move(k,0); clear(); standout(); printw(msg("newpasswd_c",0,lang),PASS_MAX); standend(); k += 2; move(k,0); printw(msg("newpasswd_c",6,lang)); refresh(); k += 2; move(k,0); if (confrecord->userrecord.seclevel == HIGHSECURITY) { writetouser(confrecord,msg("newpasswd_c",1,lang)); cmd[0] = '\0'; return(0); } if (strcmp(confrecord->userrecord.name,confrecord->sysop) == 0) { k += 2; move(k,0); addstr(msg("newpasswd_c",2,lang)); readfromuser(username,confrecord->userrecord.name,S_STRLEN,TRUE, confrecord); } else { strcpy(username,confrecord->userrecord.name); } if (*username=='\0' || strchr(username,ESCAPE_KEY)!=NULL) { cmd[0] = '\0'; return(0); } k += 2; move(k,0); addstr(msg("newpasswd_c",3,lang)); readfromuser(str,NULL,PASS_MAX,FALSE,confrecord); if (*str=='\0' || strchr(str,ESCAPE_KEY)!=NULL) { cmd[0] = '\0'; return(0); } strcpy(newpasswd,str); k++; move(k,0); addstr(msg("newpasswd_c",4,lang)); readfromuser(str,NULL,PASS_MAX,FALSE,confrecord); if (strncmp(newpasswd,str,PASS_MAX) != 0) { writetouser(confrecord,msg("newpasswd_c",5,lang)); cmd[0] = '\0'; return(0); } strcpy(str,cmd); sprintf(cmd,"%s %s %s",str,username,newpasswd); return(2); } int sprache_c(char cmd[], const confrecordtyp *confrecord) { int lang, ypos, k; char key; char cset[] = {'A','B','Q','\0'}; lang = confrecord->userrecord.lang; move(0,0); clear(); standout(); addstr(msg("sprache_c",0,lang)); standend(); move(2,2); addstr(msg("sprache_c",1,lang)); addstr(sprachennamen[confrecord->userrecord.lang]); for (k=0; k<2; k++) { ypos = k + 5; move(ypos,2); addch('['); standout(); addch('A'+k); standend(); addch(']'); move(ypos,6); addstr(sprachennamen[k]); } ypos = k + 6; move(ypos,2); addch('['); standout(); addch('Q'); standend(); addch(']'); move(ypos,6); addstr(msg("sprache_c",2,lang)); key = getkeyonprompt(msg("sprache_c",3,lang), cset, TRUE, FALSE, "lang", confrecord); if (key==ESCAPE_KEY || key=='Q') return(0); k = 1; if (key == 'A') { strcat(cmd," d"); } else if (key == 'B') { strcat(cmd," e"); } else { k = 0; } return(k); } int autozmodem_c(char cmd[], const confrecordtyp *confrecord) { int lang, ypos, k; char key; char cset[] = {'A','Q','\0'}; lang = confrecord->userrecord.lang; move(0,0); clear(); standout(); addstr(msg("autozmodem_c",0,lang)); standend(); move(2,2); if (confrecord->userrecord.autozmodem) { addstr(msg("autozmodem_c",1,lang)); } else { addstr(msg("autozmodem_c",2,lang)); } ypos = 4; move(ypos,2); addch('['); standout(); addch('A'); standend(); addch(']'); move(ypos,6); addstr(msg("autozmodem_c",3,lang)); ypos += 2; move(ypos,2); addch('['); standout(); addch('Q'); standend(); addch(']'); move(ypos,6); addstr(msg("autozmodem_c",4,lang)); key = getkeyonprompt(msg("autozmodem_c",5,lang), cset, TRUE, FALSE, "autoz", confrecord); if (key==ESCAPE_KEY || key=='Q') return(0); k = 1; if (key == 'A') { if (confrecord->userrecord.autozmodem) { strcat(cmd," n"); } else { strcat(cmd," j"); } } else { k = 0; } return(k); } int fullist_c(char cmd[], const confrecordtyp *confrecord) { int lang, ypos, k; char key; char cset[] = {'A','Q','\0'}; lang = confrecord->userrecord.lang; move(0,0); clear(); standout(); addstr(msg("fullist_c",0,lang)); standend(); move(2,2); if (confrecord->userrecord.fullist_on_cd) { addstr(msg("fullist_c",1,lang)); } else { addstr(msg("fullist_c",2,lang)); } ypos = 4; move(ypos,2); addch('['); standout(); addch('A'); standend(); addch(']'); move(ypos,6); addstr(msg("fullist_c",3,lang)); ypos += 2; move(ypos,2); addch('['); standout(); addch('Q'); standend(); addch(']'); move(ypos,6); addstr(msg("fullist_c",4,lang)); key = getkeyonprompt(msg("fullist_c",5,lang), cset, TRUE, FALSE, "dironcd", confrecord); if (key==ESCAPE_KEY || key=='Q') return(0); k = 1; if (key == 'A') { if (confrecord->userrecord.fullist_on_cd) { strcat(cmd," n"); } else { strcat(cmd," j"); } } else { k = 0; } return(k); } int put_c(char cmd[], const confrecordtyp *confrecord) { if (confrecord->userrecord.protokoll == ZMODEMPROTO && confrecord->userrecord.autozmodem) { writetouser(confrecord,msg("put_c",0,confrecord->userrecord.lang)); cmd[0] = '\0'; } return(0); } int protokoll_c(char cmd[], const confrecordtyp *confrecord) { int lang, ypos, k; char key; char cset[] = {'A','B','Q','\0'}; lang = confrecord->userrecord.lang; move(0,0); clear(); standout(); addstr(msg("protokoll_c",0,lang)); standend(); move(2,2); addstr(msg("protokoll_c",1,lang)); addstr(protokollnamen[confrecord->userrecord.protokoll]); for (k=0; k<2; k++) { ypos = k + 5; move(ypos,2); addch('['); standout(); addch('A'+k); standend(); addch(']'); move(ypos,6); addstr(protokollnamen[k]); } ypos = k + 6; move(ypos,2); addch('['); standout(); addch('Q'); standend(); addch(']'); move(ypos,6); addstr(msg("protokoll_c",2,lang)); key = getkeyonprompt(msg("protokoll_c",3,lang), cset, TRUE, FALSE, "proto", confrecord); if (key==ESCAPE_KEY || key=='Q') return(0); k = 1; if (key == 'A') { strcat(cmd," k"); } else if (key == 'B') { strcat(cmd," z"); } else { k = 0; } return(k); } int term_c(char cmd[], confrecordtyp *confrecord) { int lang, n, x_p, y_p; boolean notexists, action = FALSE; char buf[S_STRLEN+1], str[3*S_STRLEN+1], cstr[S_STRLEN+1], *sp, key; tlistetyp *tliste = (tlistetyp *)0; lang = confrecord->userrecord.lang; n = 0; if (*confrecord->termtable != '\0') { if ((sp=selectterm_c(confrecord->termtable,confrecord)) != NULL) { if (termexists(sp)) { strcpy(buf,sp); n = 1; } else { errormsg(E_LOGFILE|E_USER|E_CONSOLE,confrecord,"bbs","term_c", "Wrong termtype %s\nin termfile %s",sp,confrecord->termtable); } } } move(0,0); clear(); standout(); addstr(msg("term_c",4,lang)); standend(); printw(msg("term_c",5,lang)); printw(msg("term_c",0,lang),confrecord->userrecord.term); strcpy(str," "); if (n == 0) { do { refresh(); getyx(stdscr,y_p,x_p); n = readfromuser(buf, NULL, S_STRLEN, TRUE, confrecord); if (n>0 && ! termexists(buf)) { notexists = TRUE; printw(msg("term_c",1,lang),buf); } else { notexists = FALSE; } } while (notexists); } else { printw("%s\n",buf); } if (n > 0) { action = TRUE; } else { strcpy(buf,confrecord->userrecord.term); move(y_p,x_p); addstr(buf); } strcat(str,buf); printw(msg("term_c",2,lang),confrecord->userrecord.lines); refresh(); strcat(str," "); getyx(stdscr,y_p,x_p); if (readfromuser(buf, NULL, S_STRLEN, TRUE, confrecord) > 0) { action = TRUE; } else { sprintf(buf,"%d",confrecord->userrecord.lines); move(y_p,x_p); addstr(buf); } strcat(str,buf); printw(msg("term_c",3,lang),confrecord->userrecord.columns); refresh(); strcat(str," "); getyx(stdscr,y_p,x_p); if (readfromuser(buf, NULL, S_STRLEN, TRUE, confrecord) > 0) { action = TRUE; } else { sprintf(buf,"%d",confrecord->userrecord.columns); move(y_p,x_p); addstr(buf); } strcat(str,buf); for (n=0; charsets[n] != NULL; n++) { strcpy(cstr,"F"); strcat(cstr,charsets[n]); addstrtoliste(&tliste,TRUE,n,TL_BLOCKLEN,cstr,confrecord); } key = selectpager_c(tliste,n,msg("term_c",6,lang),NULL,TRUE,"charset", confrecord); if (key != ESCAPE_KEY) { for (n=0; charsets[n] != NULL; n++) { readliste(&tliste,FALSE,n,TL_BLOCKLEN,&sp,confrecord); if (*sp == 'T') { strcpy(confrecord->userrecord.charset,&sp[1]); action = TRUE; break; } } } removeliste(&tliste,TRUE,TL_BLOCKLEN); if (! action) return(0); strcat(cmd,str); return(3); } char *selectterm_c(const char *termfile, const confrecordtyp *confrecord) { int anz, znr, n; char key, *sp, *zp[3], zeile[2*S_STRLEN+1]; static char termname[2*S_STRLEN+3]; tlistetyp *tliste; FILE *fp; if (termfile == NULL) return NULL; if ((fp=fopen(termfile,"r")) == NULL) { errormsg(E_LOGFILE|E_CONSOLE,confrecord,NULL,"selectterm_c", "fopen %s: %m",termfile); return(NULL); } tliste = (tlistetyp *)0; /* addstrtoliste(&tliste,TRUE,0,TL_BLOCKLEN,"",confrecord); */ anz = 0; znr = 0; while((n=fgetnln(zeile,2*S_STRLEN,fp)) >= 0) { znr++; if (n > 2*S_STRLEN) { errormsg(E_LOGFILE|E_CONSOLE,confrecord,NULL,"selectterm_c", "line %i too long",znr); return(NULL); } n = splitstring(zp,zeile,'|',2); if (n>0 && *zp[0]!='\0' && *zp[0]!='#') { #ifdef CHECKTERMTABLE if (termexists(zp[0])) { if (zp[1] == NULL) zp[1] = ""; sprintf(termname,"F%-12s %s",zp[0],zp[1]); addstrtoliste(&tliste,TRUE,anz++,TL_BLOCKLEN,termname,confrecord); } else { errormsg(E_LOGFILE|E_CONSOLE,confrecord,NULL,"selectterm_c", "Terminaltype %s does not exist",zp[0]); } #else if (zp[1] == NULL) zp[1] = ""; sprintf(termname,"F%-12s %s",zp[0],zp[1]); addstrtoliste(&tliste,TRUE,anz++,TL_BLOCKLEN,termname,confrecord); #endif } } fclose(fp); key = selectpager_c(tliste,anz,msg("selectterm_c",0, confrecord->userrecord.lang),NULL,TRUE,"selectterm", confrecord); if (key != ESCAPE_KEY) { for (n=0; n<anz; n++) { readliste(&tliste,FALSE,n,TL_BLOCKLEN,&sp,confrecord); if (*sp == 'T') { splitstring(zp,sp,' ',2); strcpy(termname,&(zp[0][1])); removeliste(&tliste,TRUE,TL_BLOCKLEN); return(termname); } } } removeliste(&tliste,TRUE,TL_BLOCKLEN); if (key == RETURN_KEY) { strcpy(termname,confrecord->userrecord.term); return(termname); } return(NULL); } int selectdir_c(char argstr[], const chrootrecordtyp *chrootrecord, const char *helpcontext, const confrecordtyp *confrecord) { UID_T euid; GID_T egid; int k, n, dnr, danz, lang, len, maxlen; char key, str[S_STRLEN+NAME_MAX+2], *sp; char *homedirstr = "FHOME (Homedirectory)"; const char *csp; boolean fullist; DIR *dp; struct dirent *dirp; struct stat stats; tlistetyp *tliste; lang = confrecord->userrecord.lang; fullist = confrecord->userrecord.fullist_on_cd; if ((dp=opendir(".")) == NULL) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","selectdir_c","opendir .: %m"); return(-1); } euid = geteuid(); egid = getegid(); tliste = (tlistetyp *)0; dnr = 0; addstrtoliste(&tliste,TRUE,dnr,TL_BLOCKLEN,homedirstr,confrecord); while ((dirp=readdir(dp)) != NULL) { if (strcmp(dirp->d_name,".") == 0) continue; if (stat(dirp->d_name,&stats) < 0) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","selectdir_c","stat %s: %m", dirp->d_name); continue; } if (S_ISDIR(stats.st_mode)) { n = getperms(&stats,euid,egid); if ((n & PERM_R) && (n & PERM_X)) { dnr++; strcpy(str,"F"); strcat(str,dirp->d_name); addstrtoliste(&tliste,TRUE,dnr,TL_BLOCKLEN,str,confrecord); } } else if (fullist && S_ISREG(stats.st_mode) && (PERM_R & getperms(&stats,euid,egid))) { dnr++; sprintf(str,"X(%s) %s",msg("selectdir_c",2,lang),dirp->d_name); addstrtoliste(&tliste,TRUE,dnr,TL_BLOCKLEN,str,confrecord); } } closedir(dp); danz = dnr + 1; sortliste(tliste,TL_BLOCKLEN,danz,confrecord); maxlen = COLS - strlen(msg("selectdir_c",1,lang)) - 2; len = strlen(chrootrecord->cwdname); if (len > maxlen) { maxlen -= 4; csp = strchr(chrootrecord->cwdname,'/'); while (len > maxlen) { csp = strchr(++csp,'/'); if (csp == NULL) return(-1); len = strlen(csp); } sprintf(str,"%s: ....%s",msg("selectdir_c",1,lang),csp); } else { sprintf(str,"%s: %s",msg("selectdir_c",1,lang),chrootrecord->cwdname); } key = selectpager_c(tliste,danz,msg("selectdir_c",0,lang),str,TRUE, helpcontext,confrecord); n = -1; if (key != ESCAPE_KEY) { for (k=0; k<danz; k++) { readliste(&tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); if (*sp == 'T') { if (strcmp(&(homedirstr[1]),&(sp[1])) == 0) { n = 0; } else { strmaxcat(argstr," ",PATH_MAX); strmaxcat(argstr,&(sp[1]),PATH_MAX); n = 1; } break; } } } else { n = -1; } removeliste(&tliste,TRUE,TL_BLOCKLEN); return n; } int selectfiles_c(char argstr[], const int maxn, const char *helpcontext, const confrecordtyp *confrecord) { UID_T euid; GID_T egid; int k, n, fnr, fanz; char *sp, key, str[NAME_MAX+2]; const char *mp; DIR *dp; struct dirent *dirp; struct stat stats; tlistetyp *tliste; if ((dp=opendir(".")) == NULL) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","selectfiles_c", "opendir .: %m"); return(-1); } euid = geteuid(); egid = getegid(); tliste = (tlistetyp *)0; /* addstrtoliste(&tliste,TRUE,0,TL_BLOCKLEN,"",confrecord); */ fnr = -1; while ((dirp=readdir(dp)) != NULL) { if (stat(dirp->d_name,&stats) < 0) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","selectfiles_c","stat %s: %m", dirp->d_name); removeliste(&tliste,TRUE,TL_BLOCKLEN); closedir(dp); return(-1); } if (S_ISREG(stats.st_mode) && (PERM_R & getperms(&stats,euid,egid))) { fnr++; strcpy(str,"F"); strcat(str,dirp->d_name); addstrtoliste(&tliste,TRUE,fnr,TL_BLOCKLEN,str,confrecord); } } closedir(dp); fanz = fnr + 1; sortliste(tliste,TL_BLOCKLEN,fanz,confrecord); switch (maxn) { case 0: mp = msg("selectfiles_c",0,confrecord->userrecord.lang); break; case 1: mp = msg("selectfiles_c",1,confrecord->userrecord.lang); break; default: mp = msg("selectfiles_c",2,confrecord->userrecord.lang); break; } key = selectpager_c(tliste,fanz,mp,NULL, maxn==0, helpcontext,confrecord); if (key != ESCAPE_KEY) { for (k=0, n=0; k<fanz; k++) { readliste(&tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); if (*sp == 'T') { strmaxcat(argstr," ",ARG_MAX); strmaxcat(argstr,&(sp[1]),ARG_MAX); n++; } } } else { n = -1; } removeliste(&tliste,TRUE,TL_BLOCKLEN); if (strlen(argstr) + environlen() + 100 > ARG_MAX || n > MAXARGS-1) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","selectfiles_c", msg("selectfiles_c",3,confrecord->userrecord.lang)); n = -1; } return n; } char selectpager_c(tlistetyp *tliste, const int anz, const char *header, const char *subheader, const boolean hotselect, const char *helpcontext, const confrecordtyp *confrecord) { int kopfzeilen, lines, zstep, offset, ypos, kmax, k, n; char *zary[MAXMEN], *sp, key; clear(); move(0,0); standout(); addstr(header); standend(); if (subheader != (char *)0) { kopfzeilen = 3; move(1,0); addstr(subheader); } else { kopfzeilen = 2; } lines = confrecord->userrecord.lines - kopfzeilen -1; if (lines > MAXMEN) lines = MAXMEN; zstep = lines - 2; offset = 0; do { move(kopfzeilen,0); clrtobot(); kmax = offset+lines > anz ? anz : offset+lines; for (k=offset,n=0; k<kmax; k++,n++) { ypos = kopfzeilen + k - offset; readliste(&tliste,FALSE,k,TL_BLOCKLEN,&(zary[n]),confrecord); if (*zary[n]!='X') { move(ypos,2); addch('['); standout(); addch('A'+k-offset); standend(); addch(']'); } move(ypos,6); addstr_withmargin(&(zary[n][1])); } if (anz > lines) { if (offset+lines < anz) { n = offset +1; } else { n = 0; } } else { n = -1; } key = menueselect_c(zary,kmax-offset,n,kopfzeilen,hotselect,helpcontext, confrecord); if (key == ALLQUANTOR_KEY) { wildcardselect_c(key,tliste,anz,confrecord); } if (pagerstep(key) < 0) { offset -= zstep; } else if (pagerstep(key) > 0) { offset += zstep; } if (alphastep_c(key) > 0) { for (k=0; k<anz; k++) { readliste(&tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); if (*sp && toupper(*(sp+1)) >= key) break; } if (k > 0 && *sp && toupper(*(sp+1)) > key) k--; offset = k; } if (offset > anz-lines) offset = anz-lines; if (offset < 0) offset = 0; } while (selectpagerquit_c(key) == 0); return key; } char menueselect_c(char *zary[], const int lines, const int position, const int kopfzeilen, const boolean hotselect, const char *helpcontext, const confrecordtyp *confrecord) { int n, k, lang; boolean canselect; char prompt[S_STRLEN+1], keyset[2*MAXMEN+10], lastselkey, key, c; lang = confrecord->userrecord.lang; lastselkey = 'a'; for (k=0,n=0; n<lines; n++) { if (*zary[n] != 'X') { lastselkey = 'a' + n; keyset[k++] = lastselkey; } } canselect = (k > 0); for (n='A'; n<='Z'; n++) keyset[k++] = n; keyset[k++] = SPACE_KEY; keyset[k++] = BACKSPACE_KEY; keyset[k++] = DELETE_KEY; keyset[k++] = NEWLINE_KEY; keyset[k++] = RETURN_KEY; if (! hotselect) keyset[k++] = ALLQUANTOR_KEY; keyset[k] = '\0'; if (lines > 0) { if (position == 0) { strcpy(prompt,msg("menueselect_c",0,lang)); } else if (position == 1) { strcpy(prompt,msg("menueselect_c",1,lang)); } else if (position > 0) { sprintf(prompt,msg("menueselect_c",2,lang), position); } else { strcpy(prompt,msg("menueselect_c",3,lang)); } if (canselect) { strcat(prompt,msg("menueselect_c",5,lang)); k = strlen(prompt); prompt[k++] = toupper(lastselkey); if (! hotselect) { prompt[k++] = ','; prompt[k++] = ALLQUANTOR_KEY; } prompt[k] = '\0'; strcat(prompt,"]>"); } else { strcat(prompt,msg("menueselect_c",6,lang)); } } else { strcpy(prompt,msg("menueselect_c",4,lang)); } do { for (k=0; k<lines; k++) { move(k+kopfzeilen,0); c = *zary[k]; if (c == 'T') { addch('*'); } else if (ispunct(c)) { addch(c); } else { addch(' '); } } key = getkeyonprompt(prompt,keyset,FALSE,FALSE,helpcontext,confrecord); if (key >= 'a' && key <= 'z') { k = key - 'a'; if (k>=0 && k<lines) { c = *zary[k]; if (c == 'F' || ispunct(c)) { *zary[k] = 'T'; if (hotselect) key = RETURN_KEY; } else if (c == 'T') { *zary[k] = 'F'; } } } } while (selectpagerquit_c(key) == 0 && pagerstep(key) == 0 && wildcardchar_c(key) == 0 && alphastep_c(key) == 0); return key; } #ifndef NO_REGCOMP #define NO_RE_COMP #endif int wildcardselect_c(const char key, tlistetyp *f_tliste, const int fanz, const confrecordtyp *confrecord) { int p, k, n, lang; char str[STRLEN+1], pattern[STRLEN+1], *sp, c; #ifndef NO_REGCOMP regex_t preg; regmatch_t pmatch[1]; #else #endif lang = confrecord->userrecord.lang; move(LINES-1,0); clrtoeol(); standout(); addstr(msg("wildcardselect_c",1,lang)); standend(); refresh(); c = bbsgetch(TRUE); if (c == '?') { #ifndef NO_REGCOMP writetouser(confrecord,msg("wildcardselect_c",2,lang)); #else #ifndef NO_RE_COMP writetouser(confrecord,msg("wildcardselect_c",3,lang)); #endif #endif refresh(); c = bbsgetch(TRUE); } if (c == ESCAPE_KEY || c == RETURN_KEY || c == NEWLINE_KEY) { return(0); } else { str[0] = c; str[1] = '\0'; if (readfromuser(str,str,STRLEN,TRUE,confrecord) == 0) return 0; } /* k = 0; while (c!=ESCAPE_KEY && c!=RETURN_KEY && c!=NEWLINE_KEY && k<STRLEN) { if (k>0 && (c==BACKSPACE_KEY || c==DELETE_KEY)) { getyx(stdscr,n,p); mvdelch(n,--p); k--; } else { addch(c); str[k++] = c; } refresh(); c = bbsgetch(TRUE); }; if (c == ESCAPE_KEY) return(0); str[k] = '\0'; */ /* Shell-Metazeichen umwandeln in RE */ p = 0; pattern[p++] = '^'; k = 0; while ((c=str[k++]) != '\0') { switch (c) { case '.': pattern[p++] = '\\'; pattern[p++] = '.'; break; case '*': pattern[p++] = '.'; pattern[p++] = '*'; break; #ifndef NO_REGCOMP case '?': pattern[p++] = '.'; break; #endif default: pattern[p++] = c; } } pattern[p++] = '$'; pattern[p] = '\0'; /* RE compilieren */ #ifndef NO_REGCOMP if ((k=regcomp(&preg,pattern,REG_EXTENDED|REG_NOSUB)) != 0) { regerror(k,&preg,pattern,STRLEN); #else #ifndef NO_RE_COMP if ((sp=re_comp(pattern)) != (char *)0) { strcpy(pattern,sp); #endif #endif errormsg(E_LOGFILE|E_USER,confrecord,"bbs","wildcardselect_c", msg("wildcardselect_c",0,lang),pattern); return(-1); } for (k=0,n=0; k<fanz; k++) { readliste(&f_tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); #ifndef NO_REGCOMP if ((p=regexec(&preg,&(sp[1]),0,pmatch,0)) == 0) { #else #ifndef NO_RE_COMP if ((p=re_exec(&(sp[1]))) == 1) { #endif #endif n++; *sp = (*sp == 'T') ? 'F' : 'T'; } #ifndef NO_REGCOMP else if (p != REG_NOMATCH) { regerror(p,&preg,pattern,STRLEN); errormsg(E_LOGFILE|E_USER,confrecord,"bbs","wildcardselect_c", "regexec: %s",pattern); regfree(&preg); #else #ifndef NO_RE_COMP else if (p < 0) { errormsg(E_LOGFILE|E_USER,confrecord,"bbs","wildcardselect_c", "re_exec: internal error"); #endif #endif return(-1); } } #ifndef NO_REGCOMP regfree(&preg); #endif return(n); } int selectpagerquit_c(const char key) { switch (key) { case NEWLINE_KEY: case RETURN_KEY: return(1); break; case ESCAPE_KEY: return(-1); break; } return(0); } int alphastep_c(const char key) { if (key >= 'A' && key <= 'Z') return 1; return 0; } int bbsquit_c(char argstr[], const confrecordtyp *confrecord) { char key, cset[] = {'Y','J','N','\0'}; key = getkeyonprompt(msg("bbsquit_c",0,confrecord->userrecord.lang), cset,TRUE,FALSE,"",confrecord); if (key != 'Y' && key != 'J') { argstr[0] = '\0'; return(-1); } return(0); } int wildcardchar_c(const char key) { if (key == ALLQUANTOR_KEY) return(1); return(0); } #ifdef CUSTOM_EDITCMDLINE keyboardcmd cmdline(posstruct *txt, screenstruct *scr, tlistetyp **tliste, const confrecordtyp *confrecord) { int x_p, y_p, k; char *sp, cmd[81]; const char keyset[] = {'S','A','G','C','?',ESCAPE_KEY,RETURN_KEY,'\0'}; const char *prompt = "[S]end [A]bort [G]oto line [C]mdline_off [?]help"; getyx(stdscr,y_p,x_p); scr->showcmdline = TRUE; scr->curlines = scr->lines - 1; if (y_p == scr->lines - 1) { txt->a_offset++; scrollok(stdscr,TRUE); scroll(stdscr); scrollok(stdscr,FALSE); move(y_p-1,x_p); } if (getcmd_on_prompt(cmd,80,prompt,keyset,TRUE,scr)) { switch (*cmd) { case 'S': return QuitEdit; break; case 'A': if (! txt->unsaved) return AbortEdit; if (getcmd_on_prompt(cmd,80,"really abort (your text will be lost) [Y,N]? ", "YJN",TRUE,scr)) { if (*cmd != 'N') { return AbortEdit; } } break; case 'G': if (getcmd_on_prompt(cmd,80,"goto line:",NULL,FALSE,scr)) { if (strcmp(cmd,"$") != 0) { k = atoi(cmd); } else { k = -1; } text_jump(k,txt,scr,tliste,confrecord); } break; case 'C': scr->showcmdline = FALSE; scr->curlines = scr->lines; move(scr->lines-1,0); clrtoeol(); k = txt->a_offset + scr->lines - 1; if ( k < txt->a_zeilen) { readliste(tliste,FALSE,k,TL_BLOCKLEN,&sp,confrecord); printline(sp); } move(y_p,x_p); break; case '?': showhelp(scr,confrecord); break; } } waitread(STDIN_FILENO,cmd,80,KEYBOARDIN_SEQ_DELAY); return NoCmd; } void showhelp(const screenstruct *scr, const confrecordtyp *confrecord) { int x_p, y_p; char cmd[81]; const char *keyset = "LM"; const char *prompt = "help on command-line [L] or on cursor-movement [M] ?"; const char *cmd_msg = "\ [S]end mail : send text to recipients\n\ [A]bort mail : discard text and go back to BBS-menu\n\ [G]oto line : goto line, line no will be asked for\n\ [C]mdline_off : switch command-line off. It can be switched on by\n\ pressing CTRL-X or Escape\n"; const char *cur_msg = "\ Besides terminal depended cursor-key movement:\n\ cursor-left : CTRL-B\n\ cursor-right : CTRL-F\n\ cursor-up : CTRL-P\n\ cursor-down : CTRL-N\n\ cursor to line start: CTRL-A\n\ cursor to line end : CTRL-E\n\ page-up : CTRL-V\n\ page-down : CTRL-W or ESC-v\n\ delete char left from cursor: DEL or Backspace\n\ clear (kill) line: CTRL-K\n\ redraw screen: CTLR-R"; getyx(stdscr,y_p,x_p); if (getcmd_on_prompt(cmd,80,prompt,keyset,TRUE,scr)) { switch (*cmd) { case 'L': windowtext(cmd_msg," EDIT: ",0,confrecord); break; case 'M': windowtext(cur_msg," EDIT: ",0,confrecord); break; } } move(y_p,x_p); return; } #endif
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.