/* Autoconf patching by David Hedbor, neotron@lysator.liu.se */
/*********************************************************************/
/* file: session.c.c - funtions related to sessions */
/* TINTIN III */
/* (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t */
/* coded by peter unold 1992 */
/*********************************************************************/
#include <ctype.h>
#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif
#include "tintin.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
void show_session();
struct session *new_session();
extern char *get_arg_in_braces();
extern char *space_out();
extern char *mystrdup();
extern struct listnode *copy_list();
extern struct listnode *init_list();
extern int sessionsstarted;
extern struct session *sessionlist, *activesession;
extern struct listnode *common_aliases, *common_actions, *common_subs;
extern struct listnode *common_myvars, *common_highs, *common_antisubs;
extern struct listnode *common_pathdirs;
extern char vars[10][BUFFER_SIZE]; /* the %0, %1, %2,....%9 variables */
/************************/
/* the #session command */
/************************/
struct session *session_command(arg, ses)
char *arg;
struct session *ses;
{
char left[BUFFER_SIZE], right[BUFFER_SIZE];
struct session *sesptr;
/* struct listnode *ln; */
/* int i; */
arg=get_arg_in_braces(arg, left, 0);
arg=get_arg_in_braces(arg, right, 1);
if(!*left) {
tintin_puts("#THESE SESSIONS HAS BEEN DEFINED:", ses);
for(sesptr=sessionlist; sesptr; sesptr=sesptr->next)
show_session(sesptr);
prompt(ses);
}
else if(*left && !*right) {
for(sesptr=sessionlist; sesptr; sesptr=sesptr->next)
if(!strcmp(sesptr->name, left)) {
show_session(sesptr);
break;
}
if(sesptr==NULL) {
tintin_puts("#THAT SESSION IS NOT DEFINED.", ses);
prompt(NULL);
}
}
else {
for(sesptr=sessionlist; sesptr; sesptr=sesptr->next)
if(strcmp(sesptr->name, left)==0) {
tintin_puts("#THERE'S A SESSION WITH THAT NAME ALREADY.", ses);
prompt(NULL);
return ses;
}
ses=new_session(left, right, ses);
}
return ses;
}
/******************/
/* show a session */
/******************/
void show_session(ses)
struct session *ses;
{
char temp[BUFFER_SIZE];
sprintf(temp, "%-10s%s", ses->name, ses->address);
if(ses==activesession)
strcat(temp, " (active)");
if(ses->snoopstatus)
strcat(temp, " (snooped)");
if(ses->logfile)
strcat(temp, " (logging)");
tintin_puts2(temp, (struct session *) NULL);
prompt(NULL);
}
/**********************************/
/* find a new session to activate */
/**********************************/
struct session *newactive_session()
{
if(sessionlist) {
char buf[BUFFER_SIZE];
activesession=sessionlist;
sprintf(buf, "#SESSION '%s' ACTIVATED.", sessionlist->name);
tintin_puts(buf, NULL);
initsplit(1); /* @@@added -- perry */
}
else
tintin_puts("#THERE'S NO ACTIVE SESSION NOW.", NULL);
prompt(NULL);
return sessionlist;
}
/**********************/
/* open a new session */
/**********************/
struct session *new_session(name, address, ses)
char *name;
char *address;
struct session *ses;
{
int i,sock;
char *host, *port;
struct session *newsession;
port=host=space_out(mystrdup(address));
if(!*host) {
tintin_puts("#HEY! SPECIFY AN ADDRESS WILL YOU?", ses);
return ses;
}
while(*port && !isspace(*port))
port++;
*port++='\0';
port=space_out(port);
if(!*port) {
tintin_puts("#HEY! SPECIFY A PORT NUMBER WILL YOU?", ses);
return ses;
}
if(!(sock=connect_mud(host, port, ses)))
return ses;
newsession=(struct session *)malloc(sizeof(struct session));
newsession->name=mystrdup(name);
newsession->address=mystrdup(address);
newsession->tickstatus=FALSE;
newsession->snoopstatus=FALSE;
newsession->logfile=NULL;
newsession->ignore=DEFAULT_IGNORE;
newsession->aliases=copy_list(common_aliases, ALPHA);
newsession->actions=copy_list(common_actions, PRIORITY);
newsession->subs=copy_list(common_subs, ALPHA);
newsession->myvars=copy_list(common_myvars, ALPHA);
newsession->highs=copy_list(common_highs, ALPHA);
newsession->pathdirs=copy_list(common_pathdirs, ALPHA);
newsession->socket=sock;
newsession->antisubs=copy_list(common_antisubs, ALPHA);
newsession->socketbit=1<<sock;
newsession->next=sessionlist;
for(i=0; i<HISTORY_SIZE; i++)
newsession->history[i]=NULL;
newsession->path=init_list(newsession->path);
newsession->path_list_size=0;
newsession->path_length=0;
newsession->more_coming=0;
newsession->old_more_coming=0;
sessionlist=newsession;
activesession=newsession;
sessionsstarted++;
initsplit(1); /* @@@added -- perry */
return(newsession);
}
/*****************************************************************************/
/* cleanup after session died. if session=activesession, try find new active */
/*****************************************************************************/
void cleanup_session(ses)
struct session *ses;
{
int i;
char buf[BUFFER_SIZE];
struct session *sesptr;
sessionsstarted--;
kill_all(ses, END);
/* printf("DEBUG: Hist: %d \n\r",HISTORY_SIZE); */
/* CHANGED to fix a possible memory leak
for(i=0; i<HISTORY_SIZE; i++)
ses->history[i]=NULL;
*/
for(i=0; i<HISTORY_SIZE; i++)
if((ses->history[i]))
free(ses->history[i]);
if(ses==sessionlist)
sessionlist=ses->next;
else {
for(sesptr=sessionlist; sesptr->next!=ses; sesptr=sesptr->next);
sesptr->next=ses->next;
}
sprintf(buf, "#SESSION '%s' DIED.", ses->name);
tintin_puts(buf, NULL);
/* if(write(ses->socket, "ctld\n", 5)<5)
syserr("write in cleanup"); */ /* can't do this, cozof the peer stuff in net.c */
if(close(ses->socket)== -1)
syserr("close in cleanup");
if(ses->logfile)
fclose(ses->logfile);
initsplit(0); /* @@@added -- perry */
free(ses);
}