/* 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);
}