ftp.nice.ch/pub/next/unix/shell/guestshell.1.1.N.bs.tar.gz#/menu.c

This is menu.c in view mode; [Download] [Up]

/* menu-functions */

#include	<curses.h>
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<sys/file.h>

#include 	"prototypes.h"
#include	"global.h"

#define		INFOTEXT	"info"
#define		MAXWIDTH	256
#define		SUBJECTMAXLEN	256
#define         USERMAXLEN      256
#define		REALNAMEMAXLEN	256
#define 	PWMAXLEN	256

struct filelist {
	char fname[FILENAME_MAX];
	struct filelist *next;
};

typedef struct filelist flist;

struct menentry mentab[] = {
	"Info about this system", &sysinfo,
	"who is currently logged in ?",&who,
#ifdef MAILANYLOCAL
	"send a mail to local user",&mailpm,
#else
	"send a mail to postmaster",&mailpm,
#endif
	"chat with postmaster",&chat,
	"transfer a file",&filetrans,
	"change emulation",&chemu,
	"logoff",&logout
};
	
/* internal prototyping */
void sendfile(flist *flp);
void getfile( void );
void directory( void );
bool lookupaccess(char *pw, int *raccessp, int *waccessp, int *daccess,
					flist **flp);
static void centertext(int line, char *text);
static int drawkey(int i);

/* menu-functions */

#ifdef RESTRICTEDACCESS

char *rmfield(char *p)
{
	while(isspace(*p))
		p++;
	while(*p && !isspace(*p))
		p++;
	while(isspace(*p))
		p++;

	return p;
}

bool lookupaccess(char *pw, int *raccessp, int *waccessp, int *daccessp,
				flist **flp)
{
	FILE *h;
	char line[256], *p=line, *q;
	flist *actflp=0L;

	if(((h=fopen(FILEPWD,"r"))==0L) || (strlen(pw)<2))
		return FALSE;

	while(fgets(line, sizeof(line), h)!=0L)
		if((*line!='#') && (strncmp(line, pw, strlen(pw))==0L) &&
		   isspace(*(line+strlen(pw)))) {
			p=rmfield(p);

			/* remove comments */
			for(q=p; *q!='\0'; q++)
				if(*q=='#')
					*q='\0';

			for(q=p+strlen(p)-1; isspace(*q); *q--='\0')
				;

			*raccessp=atoi(p);
			*waccessp=atoi(p=rmfield(p));
			*daccessp=atoi(p=rmfield(p));
	
			while(*(p=rmfield(p))) {
				if(!actflp) 
					*flp=actflp=malloc(sizeof(flist));
				else {
					actflp->next=malloc(sizeof(flist));
					actflp=actflp->next;
				}
				strcpy(actflp->fname, p);
				/* the following part may cause length-
						problems */
				for(q=actflp->fname; *q!='\0'; q++)
					if(isspace(*q))
						*q='\0';
			}

			if(actflp)
				actflp->next=0L;

			return TRUE;		
		}

	fclose(h);
	return FALSE;
}

#endif

void sendfile(flist *flp)
{
	char fname[FILENAME_MAX], shcmd[SHCMDLEN];
	char *strrchr();
	flist *p;

	sprintf(fname, "%s/", PUBDIR);

	if((flp!=0L) && (flp->next==0L)) {
		strcat(fname, flp->fname);
		printf("\n\nfile to be transmitted: %s.\n\n", fname);
	}
	else {
		if(flp!=0L) {
			printf("\n\navailable files:");
			p=flp;
			while(p) {
				printf("\n%s", p->fname);
				p=p->next;
			}
		}
		printf("\n\nname of file to be sent >");
		refresh();
		gets(fname+strlen(fname));
		if(flp!=0L) {
			p=flp;
			while(p) {
				if(strcmp(strrchr(fname,'/')+1, p->fname)==0L)
					break;
				p=p->next;
			}
			if(!p) {
				printf("\n\nillegal file requested.\n\n"
						"> key <");
				refresh();
				readchar();
				return;
			}
		}
	}
	
	if(access(fname,R_OK)==-1) { 
		printf("\n\nerror - file doesn't exist.\n\n");
		refresh();
		readchar();
	}
	else {
		printf("\n\ngive your local %s-receive command now !\n\n",
				PROTNAME);
		refresh();
		sprintf(shcmd,"%s %s", SENDFILE, fname);
		if(system(shcmd))
			perror("system");
		log("sent file %s.", fname);
		readchar();
	}
}

void getfile()
{
	char shcmd[SHCMDLEN], currdir[FILENAME_MAX];
#ifdef RECNEEDSFNAME
	char fname[FILENAME_MAX];
	
	sprintf(fname, "%s/", PUBDIR);
	printf("\n\nname of file to be received >");
	refresh();
	gets(fname+strlen(fname));
	
	if(access(fname,F_OK)==0) { 
		printf("\n\nerror - file already exists.\n\n");
		refresh();
		readchar();
	}
#endif
	getwd(currdir);
	chdir(PUBDIR);
	printf("\n\ngive your local %s-send command now !\n\n",
				PROTNAME);
	refresh();

#ifdef RECNEEDSFNAME
	sprintf(shcmd,"%s %s", RECFILE, fname);
#else
	strcpy(shcmd, RECFILE);
#endif
	if(system(shcmd))
		perror("system");

#ifdef RECNEEDSFNAME
	log("received file %s.", fname);
#else
	log("received a file.");
#endif

	chdir(currdir);
	readchar();
}

void directory()
{
	char shcmd[SHCMDLEN];

	printf("\n\n");
	sprintf(shcmd,"%s -l %s", LS, PUBDIR);
	system(shcmd);
	printf("\n\n> key <");
	refresh();
	readchar();
}

void filetrans()
{
	char name[REALNAMEMAXLEN], pw[PWMAXLEN], tmp[256];
	char c;
	int raccess=TRUE, waccess=TRUE, daccess=TRUE;
	flist *flp=0L, *fltmp;

	erasescreen();
	if(*FILEMSG!='\0')
	{
		printf("%s\n\n> key <",FILEMSG);
		refresh();
		readchar();
	}
	
#ifdef RESTRICTEDACCESS
	erasescreen();
	endwin();
	centertext(2,"Filetransfer");
	centertext(3,"--------------");
	printf("\n\n");
	printf("please enter your REAL name >");
	if(!*gets(name))
		return;
	printf("please enter your password  >");
	gets(pw);

	if(lookupaccess(pw, &raccess, &waccess, &daccess, &flp)) {
		printf("\n\nOk...\n\n");
		log("'%s' entered filetransfer-menu. access-flags: %d %d %d",
				name, raccess, waccess, daccess);
	} else {
		printf("\n\naccess denied.\n\n> key <");
		log("filetransfer-access denied to '%s'", name);
		readchar();
		return;
	}
	
	initscr();
	refresh();
#endif
	erasescreen();
	centertext(2,"Filetransfer");
	centertext(3,"--------------");
	sprintf(tmp,"Transfer-Protocol: %s", PROTNAME);
	centertext(5,tmp);
	if(raccess)
		centertext(8,"1 --> receive file ( download )");
	if(waccess)
		centertext(10,"2 --> send file ( upload )");
	if(daccess)
		centertext(12,"3 --> list available files");
	centertext(15,"your choice ? >");
	refresh();
	endwin();
	c=readchar(); 
	switch(c) {
		case '1' : if(raccess) sendfile(flp);
			   break;
		case '2' : if(waccess) getfile();
			   break;
		case '3' : if(daccess) directory();
			   break;
	}

	if(flp!=0L) {
		fltmp=flp->next;
		free(flp);
		flp=fltmp;
	}
	
	initscr();
	refresh();
}

void chat()
{
        char shcmd[SHCMDLEN];

	erasescreen();
	if(*CHATMSG!='\0')
	{
		printf("%s\n\n> key <",CHATMSG);
		refresh();
		readchar();
	}

	endwin();
	sprintf(shcmd,"%s %s",TALKBIN, POSTMASTER);
	system(shcmd);

	initscr();
	refresh();
}

void chemu()
{
	erasescreen();
	setemu(TRUE);
}

void mailpm()
{
	char subject[SUBJECTMAXLEN], tmpfile[FILENAME_MAX];
	char shcmd[SHCMDLEN];
	char user[USERMAXLEN];

	strcpy(user, POSTMASTER);

	erasescreen();
	if(*MAILMSG!='\0')
	{
		printf("%s\n\n> key <",MAILMSG);
		refresh();
		readchar();
	}

	strcpy(tmpfile,tmpnam(0L));
	remove(tmpfile);
	endwin();

#ifdef MAILANYLOCAL
	do {
	  printf("\nMail to which local user ? ( CR = postmaster ) >");
	  gets(user);
	}  while(((strpbrk(user,NETWORKCHARS)!=0L) ||
		 (getpwnam(user)==0L)) && (*user!='\0'));

	if(*user=='\0')
	  strcpy(user,POSTMASTER);

#endif

	log("user send's mail to '%s'.", user);

#ifdef USEEDITOR
	sprintf(shcmd,"%s %s",EDITORBIN,tmpfile);
	if(system(shcmd))
	  perror("system");

#else
	initscr();
	erasescreen();
	endwin();
	printf("enter your text now. ^D to end.\n\n");
	refresh();
	sprintf(shcmd,"%s >%s",CATBIN,tmpfile);
	if(system(shcmd))
	  perror("system");
#endif
	erasescreen();
	/* Curses turned off here ! */
	printf("Mail to %s\n\n\nSubject: ", user);
	gets(subject);
	if(*subject=='\0')
	  strcpy(subject,DEFAULTSUBJECT);

	printf("\n\nreally send mail ? (Y/n) >");
	refresh();
	if(toupper(readchar())!='N') {
	  sprintf(shcmd, "%s -s '%s' %s <%s", MAILBIN,
		                 subject, user, tmpfile);
	  if(system(shcmd))
	    perror("system");
	}
	else
	  printf("\n\nmail not send...");
	
	initscr();
	refresh();
}

void sysinfo()
{
	showfile(INFOTEXT);
}

void logout()
{
	erasescreen();
	centertext(3,"Shure to quit ? (Y/n) >");
	refresh();
	if(toupper(readchar())!='N')
	{
		printf("\n\n\n%s\n",GOODBYETXT);
		refresh();
		endwin();
		exit(EXIT_SUCCESS);
	}
}

void who()
{
        int i;

	erasescreen();
	if(*WHOHEADLINE!='\0')
	{
		printf("%s\n",WHOHEADLINE);
		for(i=1;i<=strlen(WHOHEADLINE);i++)
			putchar('-');
		putchar('\n');
		refresh();
	}

	endwin();
	if(system(WHOBIN))
	  perror("system");

	printf("\n\n> key <");
	refresh();
	readchar();
	initscr();
}

void centertext(int line, char *text)
{
	mvcur(stdscr->_cury, stdscr->_curx,
		line, (COLS-strlen(text))/2);
	printf("%s",text);
}

void drawmenu()
{
	char outstr[MAXWIDTH];
	int i;

	erasescreen();
	centertext(0,HEADLINE);
	centertext(2,MENUTITLE);

	for(i=1;i<=(sizeof(mentab)/sizeof(struct menentry));i++)
	{
		sprintf(outstr,"%d  -->  %s",i,mentab[i-1].text);
		centertext(i*2+2,outstr);
	}

	centertext(LINES-2,"your choice >");
	refresh();
}

int drawkey(int i)
{

	return i;
}

int getmenukey()
{
	int i;

	while( ((i=(readchar()&0xf))<1) || 
			(i>(sizeof(mentab)/sizeof(struct menentry))) ) 
		drawmenu();

	refresh();
	return(drawkey(i));
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.