/*********************************************************************/
/* 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>
#include <string.h>
#include "tintin.h"
extern int sessionsstarted;
extern struct session *sessionlist, *activesession;
extern struct listnode *common_aliases, *common_actions, *common_subs;
extern char vars[10][BUFFER_SIZE]; /* the &0, &1, &2,....&9 variables */
/************************/
/* the #session command */
/************************/
struct session *session_command(char *arg, struct session *ses)
{
char left[BUFFER_SIZE], right[BUFFER_SIZE];
struct session *sesptr;
struct listnode *ln;
int i;
arg=get_arg_stop_spaces(arg, left);
arg=get_arg_with_spaces(arg, right);
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);
}
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);
return ses;
}
ses=new_session(left, right, ses);
}
return ses;
}
/******************/
/* show a session */
/******************/
void show_session(struct session *ses)
{
printf("%-10s%s", ses->name, ses->address);
if(ses==activesession)
printf(" (active)");
if(ses->snoopstatus)
printf(" (snooped)");
if(ses->logfile)
printf(" (logging)");
puts("");
}
/**********************************/
/* 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);
}
else
tintin_puts("#THERE'S NO ACTIVE SESSION NOW.", NULL);
return sessionlist;
}
/**********************/
/* open a new session */
/**********************/
struct session *new_session(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->aliases=copy_list(common_aliases);
newsession->actions=copy_list(common_actions);
newsession->subs=copy_list(common_subs);
newsession->socket=sock;
newsession->socketbit=1<<sock;
newsession->next=sessionlist;
for(i=0; i<HISTORY_SIZE-1; i++)
newsession->history[i]=NULL;
newsession->path_mark=0;
newsession->path_lenght=0;
sessionlist=newsession;
activesession=newsession;
sessionsstarted++;
return(newsession);
}
/*************************************************************************************/
/* cleanup after a session died. if session==activesession, then try find new active */
/*************************************************************************************/
void cleanup_session(struct session *ses)
{
int i;
char buf[BUFFER_SIZE];
struct session *sesptr;
sessionsstarted--;
kill_list(ses->aliases);
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);
free(ses);
}