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.