#include <ctype.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/socket.h>
#ifdef DMALLOC
#include <dmalloc.h>
#endif
#include "tcltk.h"
#include "window.h"
#include "quirc.h"
#include "format.h"
#include "messages.h"
#include "echo.h"
#include "command.h"
#include "tags.h"
#include "mytcl.h"
time_t lastcommand;
int TT_Proc_activebutton(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
strcpy(window.pathname,argv[1]);
windowp=windows.find(window);
if(windowp) TT_EvalF(TT_ARGS,
"QListBox::colorize .windowlist %d active",
windowp->index);
return TCL_OK;
}
int TT_Proc_bgerror(TT_PROC_ARGS) {
static int inbgerror;
char *result;
int wasinbgerror=inbgerror;
int baderror=0;
if(!inbgerror && TT_Int(TT_ARGS,"set ::internal::done_main_window")) {
inbgerror=1;
if(!(result=fparse("ERROR_INFO",-1,1,TT_Str(TT_ARGS,"set errorInfo")))) {
baderror=1;
}
if(!baderror) {
echo(result,".main",1);
if(!(result=fparse("ERROR_CODE",-1,1,TT_Str(TT_ARGS,"set errorCode")))) {
baderror=1;
}
}
if(!baderror) {
echo(result,".main",1);
if(!(result=fparse("ERROR_ADDITIONAL",-1,1,argv[1]))) {
baderror=1;
}
}
if(!baderror) {
echo(result,".main",1);
}
inbgerror=0;
}
if(wasinbgerror) {
fprintf(stderr,"********************************************************************************\n");
fprintf(stderr,M_ERROR_INFINITE_LOOP);
fprintf(stderr,"********************************************************************************\n");
}
if(baderror) {
fprintf(stderr,M_ERROR_NO_FORMAT);
}
if(baderror || wasinbgerror || !TT_Int(TT_ARGS,"set ::internal::done_main_window")) {
fprintf(stderr,"%s:\n%s\n",M_ERROR_INFO,TT_Str(TT_ARGS,"set errorInfo"));
fprintf(stderr,"%s: %s\n",M_ERROR_CODE,TT_Str(TT_ARGS,"set errorCode"));
if(argc==2) {
fprintf(stderr,"%s: %s\n",M_ERROR_ADDITIONAL,argv[1]);
}
exit(1);
}
return TCL_OK;
}
int TT_Proc_callproc(TT_PROC_ARGS) {
// argv[1] is the proc name
// argv[2] is the list of arguments to the proc
// argv[3] is the server index
if(argc!=4) {
Tcl_SetResult(interp,"Usage: callproc <procname> <argument_list> <server_index>",TCL_VOLATILE);
return TCL_ERROR;
}
TT_EvalF(TT_ARGS,"%s %s %s",argv[1],argv[3],argv[2]);
return TCL_OK;
}
int TT_Proc_channel(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
strcpy(window.pathname,currentwindow);
if((windowp=windows.find(window))) {
if(!strncmp(windowp->pathname,".channel",8)) {
Tcl_SetResult(interp,windowp->name,TCL_VOLATILE);
}
}
return TCL_OK;
}
int TT_Proc_configtags(TT_PROC_ARGS) {
configuretags(argv[1],argv[2],argv[3]);
return TCL_OK;
}
int TT_Proc_connect(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
if(argc>2) {
Tcl_SetResult(interp,"Usage: connect [<serverindex>]",TCL_VOLATILE);
return TCL_ERROR;
}
if(argc==1) {
strcpy(window.pathname,currentwindow);
} else {
sprintf(window.pathname,".status%s",argv[1]);
}
if((windowp=windows.find(window))&&windowp->server) {
windowp->server->do_connect();
}
return TCL_OK;
}
int TT_Proc_closewindow(TT_PROC_ARGS) {
tchan chan;
tchan *chanp;
tquery query;
tserver *serverp;
char temp[TEMPLEN];
twindow window;
twindow *windowp;
int newindex;
if(argc!=2) {
Tcl_SetResult(interp,"Usage: closewindow <pathname>",TCL_STATIC);
return TCL_ERROR;
}
if(strcmp(argv[1],".main")) {
strcpy(window.pathname,argv[1]);
if((windowp=windows.find(window))) {
newindex=windowp->index-1;
if(!strncmp(argv[1],".query",6)) {
TT_EvalF(TT_ARGS,"destroy %s",argv[1]);
strcpy(query.pathname,argv[1]);
windowp->server->querylist.deleteitem(query);
TT_EvalF(TT_ARGS,"QListBox::delete .windowlist %d",windowp->index);
windows.deleteitem(window);
TT_EvalF(TT_ARGS,"totop %d",newindex);
}
if(!strncmp(argv[1],".chat",5)) {
windowp->dcc->disconnect();
TT_EvalF(TT_ARGS,"destroy %s",argv[1]);
TT_EvalF(TT_ARGS,"QListBox::delete .windowlist %d",windowp->index);
delete windowp->dcc;
windows.deleteitem(window);
TT_EvalF(TT_ARGS,"totop %d",newindex);
}
if(!strncmp(argv[1],".files",6)) {
if(windowp->server->dcclist.lastindex()==-1) {
//windowp->dcc->disconnect();
TT_EvalF(TT_ARGS,"destroy %s",argv[1]);
TT_EvalF(TT_ARGS,"QListBox::delete .windowlist %d",windowp->index);
//delete windowp->dcc;
windows.deleteitem(window);
TT_EvalF(TT_ARGS,"totop %d",newindex);
}
}
if(!strncmp(argv[1],".channel",8)) {
TT_EvalF(TT_ARGS,"destroy %s",argv[1]);
strcpy(chan.pathname,argv[1]);
if((chanp=windowp->server->chanlist.find(chan))) {
if(chanp->ison) {
sprintf(temp,"PART %s",chanp->name);
// DEBUG
//TT_EvalF(TT_ARGS,".raw.text insert end \"Command (tcl.cc:173): %q\\n\"",temp);
windowp->server->senddata(temp);
}
windowp->server->chanlist.deleteitem(chan);
}
TT_EvalF(TT_ARGS,"QListBox::delete .windowlist %d",windowp->index);
windows.deleteitem(window);
TT_EvalF(TT_ARGS,"totop %d",newindex);
}
if(!strncmp(argv[1],".status",7)) {
if(windowp->server->dcclist.lastindex()==-1) {
serverp=windowp->server;
if(serverp->connected) serverp->disconnect(1);
windows.init_trav();
while((windowp=windows.trav())) {
if(serverp==windowp->server) {
if(!strncmp(windowp->pathname,".chat",5)) {
windowp->dcc->disconnect();
}
strcpy(window.pathname,windowp->pathname);
TT_EvalF(TT_ARGS,"destroy %s",windowp->pathname);
if((windowp=windows.find(window))) TT_EvalF(TT_ARGS,"QListBox::delete .windowlist %d",windowp->index);
windows.deleteitem(window);
}
}
delete serverp;
TT_EvalF(TT_ARGS,"totop %d",newindex);
}
}
}
} else {
TT_EvalF(TT_ARGS,"\
%s.text configure -state normal\n\
%s.text delete 0.0 end\n\
for { set n 0 } { $n < $::dynamic::blank_lines_before_text } { incr n } {\n\
%s.text insert end \\n\n\
}\n\
%s.text configure -state disabled\n\
%s.text yview moveto 1\
",argv[1],argv[1],argv[1],argv[1],argv[1]);
}
return TCL_OK;
}
int TT_Proc_currentindex(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
strcpy(window.pathname,currentwindow);
Tcl_SetResult(interp,"-1",TCL_VOLATILE);
if((windowp=windows.find(window))) {
if(windowp->server) {
Tcl_SetResult(interp,strnum(windowp->server->index),TCL_VOLATILE);
}
}
return TCL_OK;
}
int TT_Proc_currentwindow(TT_PROC_ARGS) {
Tcl_SetResult(interp,currentwindow,TCL_VOLATILE);
return TCL_OK;
}
int TT_Proc_disconnect(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
if(argc>2) {
Tcl_SetResult(interp,"Usage: disconnect [<serverindex>]",TCL_VOLATILE);
return TCL_ERROR;
}
if(argc==1) {
strcpy(window.pathname,currentwindow);
} else {
sprintf(window.pathname,".status%s",argv[1]);
}
if((windowp=windows.find(window))&&windowp->server) {
windowp->server->disconnect(1);
} else {
Tcl_SetResult(interp,"Usage: disconnect [<serverindex>]",TCL_VOLATILE);
return TCL_ERROR;
}
return TCL_OK;
}
int TT_Proc_echo(TT_PROC_OBJS) {
int listc;
char **listv;
int n,i;
if(objc>4||objc<2) {
Tcl_SetResult(interp,"Usage: echo <text> [<pathname>] [<activate_windowlist>]",TCL_STATIC);
return TCL_ERROR;
}
if((objc==4)&&((!strcmp(ARGV(2),"0"))||(!strcmp(ARGV(2),"1")))) {
// echo pathname activate text
echo_n(objv[3],ARGV(1),atoi(ARGV(2)));
} else {
if(objc==2) {
// echo text
if(strlen(currentwindow)) echo_n(objv[1],currentwindow,0);
return TCL_OK;
}
if(objc==3) n=1; else n=atoi(ARGV(3));
// echo text pathname [activate]
if(Tcl_SplitList(interp,ARGV(2),&listc,(const char ***)&listv)==TCL_ERROR)
return TCL_ERROR;
for(i=0;i<listc;i++) {
// The old server specific echo used to check if windows existed
echo_n(objv[1],listv[i],n);
}
Tcl_Free((char *)listv);
}
return TCL_OK;
}
int TT_Proc_echotags(TT_PROC_OBJS) {
int listc;
char **listv;
int n,i;
char *tempstring;
if(objc>4||objc<2) {
Tcl_SetResult(interp,"Usage: echotags <text> [<pathname>] [<activate_windowlist>]",TCL_STATIC);
return TCL_ERROR;
}
if(objc==2) {
// echotags text
if(strlen(currentwindow)) echotags(objv[1],currentwindow,0);
return TCL_OK;
}
if(objc==3) n=1; else n=atoi(ARGV(3));
// echotags text pathname [activate]
tempstring = mystrdup(ARGV(2));
if(Tcl_SplitList(interp,
tempstring,
&listc,
(const char ***)&listv)==TCL_ERROR) {
free(tempstring);
return TCL_ERROR;
}
free(tempstring);
for(i=0;i<listc;i++) {
echotags(objv[1],listv[i],n);
}
Tcl_Free((char *)listv);
return TCL_OK;
}
int TT_Proc_escape(TT_PROC_OBJS) {
int length;
Tcl_Obj *objptr;
char *dst;
char *currentpiece;
int flags;
if(objc!=2) {
Tcl_SetResult(interp,"usage: escape <data>",TCL_STATIC);
return TCL_ERROR;
}
currentpiece=Tcl_GetStringFromObj(objv[1],&length);
dst=(char *)malloc(Tcl_ScanCountedElementFixed(currentpiece,length,&flags));
flags|=TCL_DONT_USE_BRACES;
length=Tcl_ConvertCountedElement(currentpiece, length, dst, flags);
objptr=Tcl_NewStringObj(dst,length);
free(dst);
Tcl_SetObjResult(interp,objptr);
return TCL_OK;
}
int TT_Proc_exit(TT_PROC_ARGS) {
//foreach server [servers] {
//::template::quote $server \"QUIT :$::dynamic::default_quit\"
//}
TT_Eval(TT_ARGS,"\
shutdown\n\
die\n\
");
return TCL_OK;
}
int TT_Proc_fdisplay(TT_PROC_ARGS) {
if(argc<2) {
Tcl_SetResult(interp,"Usage: fdisplay <type> [arguments]",TCL_STATIC);
return TCL_ERROR;
}
if(!fexists(argv[1])) {
Tcl_SetResult(interp,"fdisplay: Invalid format type.",TCL_STATIC);
return TCL_ERROR;
}
fdisplayv(argv[1],-1,argc-2,&argv[2]);
return TCL_OK;
}
int TT_Proc_fgetformat(TT_PROC_ARGS) {
if(argc<2) {
Tcl_SetResult(interp,"Usage: fgetformat <type>",TCL_STATIC);
return TCL_ERROR;
}
if(!fexists(argv[1])) {
Tcl_SetResult(interp,"fdisplay: Invalid format type.",TCL_STATIC);
return TCL_ERROR;
}
Tcl_SetResult(interp,fgetformat(argv[1]),TCL_VOLATILE);
return TCL_OK;
}
int TT_Proc_fgetpathnames(TT_PROC_ARGS) {
if(argc<2) {
Tcl_SetResult(interp,"Usage: fgetpathnames <type> [arguments]",TCL_STATIC);
return TCL_ERROR;
}
if(!fexists(argv[1])) {
Tcl_SetResult(interp,"fgetpathnames: Invalid format type.",TCL_STATIC);
return TCL_ERROR;
}
Tcl_SetResult(interp,fgetpathnames(argv[1],-1,argc-2,&argv[2]),TCL_VOLATILE);
return TCL_OK;
}
int TT_Proc_flocation(TT_PROC_ARGS) {
char assemble[TEMPLEN];
if(argc!=2 && argc!=3) {
Tcl_SetResult(interp,"Usage: flocation <type> [argument]",TCL_STATIC);
return TCL_ERROR;
}
if(!strcasecmp(argv[1],"main")) {
Tcl_SetResult(interp,".main",TCL_STATIC);
return TCL_OK;
}
if(!strcasecmp(argv[1],"current")) {
Tcl_SetResult(interp,"[currentwindow]",TCL_STATIC);
return TCL_OK;
}
if(!strcasecmp(argv[1],"status")) {
Tcl_SetResult(interp,"[pathname status]",TCL_STATIC);
return TCL_OK;
}
if(!strcasecmp(argv[1],"currentorstatus")) {
Tcl_SetResult(interp,"[if { [currentindex]==[index] } { set ::internal::junk [currentwindow] } else { set ::internal::junk [pathname status] }]",TCL_STATIC);
return TCL_OK;
}
if(!strcasecmp(argv[1],"serverall")) {
Tcl_SetResult(interp,"[pathname all]",TCL_STATIC);
return TCL_OK;
}
if(!strcasecmp(argv[1],"files")) {
Tcl_SetResult(interp,"[pathname files]",TCL_STATIC);
return TCL_OK;
}
if(!strcasecmp(argv[1],"all")) {
Tcl_SetResult(interp,"[windows]",TCL_STATIC);
return TCL_OK;
}
if(!strcasecmp(argv[1],"none")) {
Tcl_SetResult(interp,"",TCL_STATIC);
return TCL_OK;
}
if(!strcasecmp(argv[1],"onchannel") && argc==3) {
sprintf(assemble,"onchannel %s",argv[2]);
Tcl_SetResult(interp,assemble,TCL_VOLATILE);
return TCL_OK;
}
if(!strcasecmp(argv[1],"channelorstatus") && argc==3) {
sprintf(assemble,"channelorstatus %s",argv[2]);
Tcl_SetResult(interp,assemble,TCL_VOLATILE);
return TCL_OK;
}
if(!strcasecmp(argv[1],"pathname") && argc==3) {
sprintf(assemble,"pathname %s",argv[2]);
Tcl_SetResult(interp,assemble,TCL_VOLATILE);
return TCL_OK;
}
if(!strcasecmp(argv[1],"chat") && argc==3) {
sprintf(assemble,"chat %s",argv[2]);
Tcl_SetResult(interp,assemble,TCL_VOLATILE);
return TCL_OK;
}
Tcl_SetResult(interp,"flocation: Invalid type or too few arguments.",TCL_STATIC);
return TCL_ERROR;
}
int TT_Proc_fparse(TT_PROC_ARGS) {
// fparse <type> [arguments]
// 0 1 2+
// argc 1 2 3
char *result;
if(argc<2) {
Tcl_SetResult(interp,"Usage: fparse <type> [arguments]",TCL_STATIC);
return TCL_ERROR;
}
if(!fexists(argv[1])) {
Tcl_SetResult(interp,"fparse: Invalid format type.",TCL_STATIC);
return TCL_ERROR;
}
if(!(result=fparsev(argv[1],-1,argc-2,&argv[2]))) {
Tcl_SetResult(interp,"fparse: Error parsing format (No argument present for format argument number?).",TCL_STATIC);
return TCL_ERROR;
}
Tcl_SetResult(interp,result,TCL_VOLATILE);
return TCL_OK;
}
int TT_Proc_fset(TT_PROC_ARGS) {
if(argc<3 || argc>5) {
Tcl_SetResult(interp,"Usage: fset <type> <format> [location [activate]]",TCL_STATIC);
return TCL_ERROR;
}
hash_set(&formats,argv[1],argv[2]);
if(argc<5) hash_set(&activate,argv[1],"1"); else hash_set(&activate,argv[1],argv[4]);
if(argc>3) {
hash_set(&locations,argv[1],argv[3]);
} else {
hash_set(&locations,argv[1],".main");
}
return TCL_OK;
}
int TT_Proc_gettags(TT_PROC_OBJS) {
Tcl_Obj *result;
char *pathname;
if(objc>3||objc<2) {
Tcl_SetResult(interp,"Usage: gettags <text> [<pathname>]",TCL_STATIC);
return TCL_ERROR;
}
if(objc==2) {
// gettags text
pathname=currentwindow;
} else {
// gettags text pathname
pathname=ARGV(2);
}
if(!strlen(pathname)) {
Tcl_SetResult(interp,"Usage: gettags <text> [<pathname>] (Pathname cannot be an empty string.)",TCL_STATIC);
return TCL_ERROR;
}
result=gettags(objv[1],pathname);
Tcl_SetObjResult(interp,result);
Tcl_DecrRefCount(result);
return TCL_OK;
}
int TT_Proc_hist(TT_PROC_ARGS) {
tcommand *commandp;
char assemble[TEMPLEN];
history.init_trav();
while((commandp=history.trav())) {
sprintf(assemble," \0030,14 HISTORY \003 %d: %s",commandp->index,commandp->line);
echo(assemble,currentwindow,1);
}
return TCL_OK;
}
int TT_Proc_histdown(TT_PROC_ARGS) {
tcommand command;
tcommand *commandp;
if(historyposition!=-1) {
if(historyposition==0) {
TT_EvalF(TT_ARGS,"%s.entry delete 0 end",currentwindow);
TT_EvalF(TT_ARGS,"%s.entry insert 0 %q",currentwindow,historycommand);
if(historycommand) free(historycommand);
historycommand=0;
historyposition--;
} else {
historyposition--;
TT_EvalF(TT_ARGS,"%s.entry delete 0 end",currentwindow);
command.index=historyposition;
commandp=history.find(command);
TT_EvalF(TT_ARGS,"%s.entry insert 0 %q",currentwindow,commandp->line);
}
}
return TCL_OK;
}
int TT_Proc_histup(TT_PROC_ARGS) {
tcommand command;
tcommand *commandp;
if((historyposition!=99)&&(historyposition<history.lastindex())) {
if(historyposition==-1) {
historycommand=strdup(TT_StrF(TT_ARGS,"%s.entry get",currentwindow));
}
historyposition++;
TT_EvalF(TT_ARGS,"%s.entry delete 0 end",currentwindow);
command.index=historyposition;
commandp=history.find(command);
TT_EvalF(TT_ARGS,"%s.entry insert 0 %q",currentwindow,commandp->line);
}
return TCL_OK;
}
int TT_Proc_idle(TT_PROC_ARGS) {
if(!lastcommand) {
Tcl_SetResult(interp,"0",TCL_STATIC);
} else {
Tcl_SetResult(interp,strnum(time(0)-lastcommand),TCL_VOLATILE);
}
return TCL_OK;
}
int TT_Proc_index(TT_PROC_ARGS) {
if(argc!=1) {
Tcl_SetResult(interp,"Usage: index",TCL_VOLATILE);
return TCL_ERROR;
}
Tcl_SetResult(interp,"-1",TCL_VOLATILE);
return TCL_OK;
}
int TT_Proc_ischannel(TT_PROC_ARGS) {
if(argc>=2) {
if(ischannel(argv[1]))
Tcl_SetResult(interp,"1",TCL_VOLATILE);
else
Tcl_SetResult(interp,"0",TCL_VOLATILE);
}
return TCL_OK;
}
int TT_Proc_memory(TT_PROC_ARGS) {
twindow *windowp;
int count=0;
windows.init_trav();
while((windowp=windows.trav())) {
count+=TT_IntF(TT_ARGS,"\
set all [%s.text dump -text 0.0 end]\n\
set ::internal::count 0\n\
for { set n 0 } { $n < [llength $all] } { incr n } {\n\
if { [lindex $all $n]==\"text\" } {\n\
incr ::internal::count [string length [lindex $all [expr $n+1]]]\n\
}\n\
}\n\
echo \"Characters in %s: $::internal::count\"\n\
set ::internal::count\n\
",windowp->pathname,windowp->pathname);
}
count+=TT_Int(TT_ARGS,"\
set all [.raw.text dump -text 0.0 end]\n\
set ::internal::count 0\n\
for { set n 0 } { $n < [llength $all] } { incr n } {\n\
if { [lindex $all $n]==\"text\" } {\n\
incr ::internal::count [string length [lindex $all [expr $n+1]]]\n\
}\n\
}\n\
echo \"Characters in .raw: $::internal::count\"\n\
set ::internal::count\n\
");
TT_EvalF(TT_ARGS,"echo \"Total Characters: %d (*3=%d)\"",count,count*3);
TT_Eval(TT_ARGS,"echo \"Memory usage: [lindex [exec cat /proc/[pid]/stat] 22]\"");
TT_EvalF(TT_ARGS,"echo \"Memory Usage minus Total Predicted: [expr [lindex [exec cat /proc/[pid]/stat] 22]-%d]\"",count*3);
/*
struct rusage usage;
if(getrusage(RUSAGE_SELF,&usage)==-1) {
perror("getrusage()");
exit(1);
}
printf("user time used: %ld and %ld\n",usage.ru_utime.tv_sec,usage.ru_utime.tv_usec);
printf("system time used: %ld and %ld\n",usage.ru_stime.tv_sec,usage.ru_stime.tv_usec);
printf("maximum resident set size: %ld\n",usage.ru_maxrss);
printf("integral shared memory size: %ld\n",usage.ru_ixrss);
printf("integral unshared data size: %ld\n",usage.ru_idrss);
printf("integral unshared stack size: %ld\n",usage.ru_isrss);
printf("page reclaims: %ld\n",usage.ru_minflt);
printf("page faults: %ld\n",usage.ru_majflt);
printf("swaps: %ld\n",usage.ru_nswap);
printf("block input operations: %ld\n",usage.ru_inblock);
printf("block output operations: %ld\n",usage.ru_oublock);
printf("messages sent: %ld\n",usage.ru_msgsnd);
printf("messages received: %ld\n",usage.ru_msgrcv);
printf("signals received: %ld\n",usage.ru_nsignals);
printf("voluntary context switches: %ld\n",usage.ru_nvcsw);
printf("involuntary context switches: %ld\n",usage.ru_nivcsw);
*/
//struct timeval ru_utime; /* user time used */
//struct timeval ru_stime; /* system time used */
//long ru_maxrss; /* maximum resident set size */
//long ru_ixrss; /* integral shared memory size */
//long ru_idrss; /* integral unshared data size */
//long ru_isrss; /* integral unshared stack size */
//long ru_minflt; /* page reclaims */
//long ru_majflt; /* page faults */
//long ru_nswap; /* swaps */
//long ru_inblock; /* block input operations */
//long ru_oublock; /* block output operations */
//long ru_msgsnd; /* messages sent */
//long ru_msgrcv; /* messages received */
//long ru_nsignals; /* signals received */
//long ru_nvcsw; /* voluntary context switches */
//long ru_nivcsw; /* involuntary context switches */
return TCL_OK;
}
int TT_Proc_microtime(TT_PROC_ARGS) {
struct timeval tv;
struct timezone tz;
char temptime[100];
tz.tz_minuteswest=0;
tz.tz_dsttime=0;
if(gettimeofday(&tv,&tz)) {
Tcl_SetResult(interp,"Error occured during call to gettimeofday()",TCL_VOLATILE);
return TCL_ERROR;
}
sprintf(temptime,"%.6f",tv.tv_sec+tv.tv_usec/1000000.0);
Tcl_SetResult(interp,temptime,TCL_VOLATILE);
return TCL_OK;
}
int TT_Proc_newserver(TT_PROC_ARGS) {
tserver *serverp;
char *check;
char *colon;
char *copy;
if(argc==1) {
serverp=new tserver("",0,"");
} else {
if(!strlen(argv[1])) {
serverp=new tserver("",0,"");
} else {
switch(argc) {
case 2:
if(!(copy=strdup(argv[1]))) {
fprintf(stderr,M_OUT_OF_MEMORY);
}
if(!(colon=strstr(copy,":"))) {
// server
serverp=new tserver(copy,0,"");
} else {
*colon=0;
colon++;
if(!(check=strstr(colon,":"))) {
// server:port
serverp=new tserver(copy,atoi(colon),"");
} else {
// server::password
// server:port:password
*check=0;
serverp=new tserver(copy,atoi(colon),check+1);
}
}
free(copy);
break;
case 3:
// server port
serverp=new tserver(argv[1],atoi(argv[2]),"");
break;
case 4:
// server port password
serverp=new tserver(argv[1],atoi(argv[2]),argv[3]);
break;
default:
Tcl_SetResult(interp,"usage: newserver [<server>[:[<port>][:<password>]]]",TCL_STATIC);
return TCL_ERROR;
}
}
}
Tcl_SetResult(interp,strnum(serverp->index),TCL_VOLATILE);
return TCL_OK;
}
int TT_Proc_nextwindow(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
strcpy(window.pathname,currentwindow);
if((windowp=windows.find(window))) {
if(windowp->index<windows.lastindex()) {
TT_EvalF(TT_ARGS,"totop %d",windowp->index+1);
} else {
TT_Eval(TT_ARGS,"totop 0");
}
}
return TCL_OK;
}
int TT_Proc_parse(TT_PROC_ARGS) {
if(argc<3) {
Tcl_SetResult(interp,"usage: parse <command> <argument> [<argument> ...]",TCL_STATIC);
return TCL_ERROR;
}
if(!strcasecmp(argv[1],"format")) {
//parse format TYPE "format string"
if(argc!=4) {
Tcl_SetResult(interp,"usage: parse format <type> <format_string>",TCL_STATIC);
return TCL_ERROR;
}
} else if(!strcasecmp(argv[1],"args")) {
//parse args TYPE "arg types"
if(argc!=4) {
Tcl_SetResult(interp,"usage: parse args <type> <input_arguments>",TCL_STATIC);
return TCL_ERROR;
}
} else if(!strcasecmp(argv[1],"location")) {
//parse location TYPE "location string"
//[parse location TYPE]
if(argc>4) {
Tcl_SetResult(interp,"usage: parse location <type> [<location_string>]",TCL_STATIC);
return TCL_ERROR;
}
} else {
//[parse TYPE args ...]
}
return TCL_OK;
}
char *mystrtok(char *s, char *delim) {
static char *nextposition;
char *position;
char *oldposition;
// DEBUG
//TT_EvalF(TT_ARGS,".raw.text insert end \"DEBUG - s is *%d*\\n\"",(int)s);
if(s) nextposition=s;
// DEBUG
//TT_EvalF(TT_ARGS,".raw.text insert end \"DEBUG - nextposition is *%d*\\n\"",(int)nextposition);
if(!nextposition) return NULL;
// DEBUG
//TT_EvalF(TT_ARGS,".raw.text insert end \"DEBUG - nextposition is non-null and is *%q*\\n\"",nextposition);
if((position=strpbrk(nextposition,delim))) {
// DEBUG
//TT_EvalF(TT_ARGS,".raw.text insert end \"DEBUG - Found a *%q*\\n\"",delim);
*position=0;
position++;
}
oldposition=nextposition;
// DEBUG
//TT_EvalF(TT_ARGS,".raw.text insert end \"DEBUG - Returning *%q*\\n\"",oldposition);
nextposition=position;
// DEBUG
//TT_EvalF(TT_ARGS,".raw.text insert end \"DEBUG - To be checked next time is *%q*\\n\"",nextposition);
return oldposition;
}
int TT_Proc_parseentry(TT_PROC_ARGS) {
// Split up long lines!!!!
// argv[1] is the origin window
tchan chan;
tchan *chanp;
tquery query;
tquery *queryp;
char temp[TEMPLEN];
char *theentry;
char *returned;
char *position;
twindow window;
twindow *windowp;
tcommand command;
if(argc!=2) {
Tcl_SetResult(interp,"Usage: parseentry <pathname>",TCL_STATIC);
return TCL_ERROR;
}
strcpy(window.pathname,argv[1]);
if((windowp=windows.find(window))) {
theentry=strdup(TT_StrF(TT_ARGS,"%s.entry get",argv[1]));
if(!theentry) {
fprintf(stderr,M_OUT_OF_MEMORY);
exit(1);
}
TT_EvalF(TT_ARGS,"%s.entry delete 0 end",argv[1]);
if(strlen(TT_StrF(TT_ARGS,"info command ::event_enter"))) {
returned=strdup(TT_StrF(TT_ARGS,"::event_enter %q %s",theentry,argv[1]));
free(theentry);
if(!returned) {
fprintf(stderr,M_OUT_OF_MEMORY);
exit(1);
}
theentry=returned;
}
if(strlen(theentry)) {
if(historycommand) free(historycommand);
historycommand=0;
historyposition=-1;
command.line=strdup(theentry);
history.insert_start(command);
if(history.lastindex()==COMMANDHISTORYLEN) {
command.index=history.lastindex();
history.deleteitem(command);
}
position=mystrtok(theentry,"\n");
while(position) {
if(!strlen(position)) {
position=mystrtok(0,"\n");
continue;
}
if(position[0]=='/') {
do_command(argv[1],position);
} else {
if(!strncmp(argv[1],".channel",8)) {
strcpy(chan.pathname,argv[1]);
if((chanp=windowp->server->chanlist.find(chan))) {
sprintf(temp,"PRIVMSG %s :%s",chanp->name,position);
windowp->server->senddata(temp);
}
}
if(!strncmp(argv[1],".query",6)) {
strcpy(query.pathname,argv[1]);
if((queryp=windowp->server->querylist.find(query))) {
sprintf(temp,"PRIVMSG %s :%s",queryp->getname(),position);
windowp->server->senddata(temp);
}
}
if(!strncmp(argv[1],".chat",5)) {
twindow window2;
twindow *windowp2;
strcpy(window2.pathname,argv[1]);
if((windowp2=windows.find(window2))) {
if(windowp2->dcc) {
windowp2->dcc->senddata(position);
}
}
}
if(strncmp(argv[1],".status",7)&&strcmp(argv[1],".main")) {
fdisplay("OUTGOING_TEXT",windowp->server->index,2,argv[1],position);
}
}
position=mystrtok(0,"\n");
}
}
free(theentry);
}
lastcommand=time(0);
return TCL_OK;
}
int TT_Proc_popup(TT_PROC_ARGS) {
//popup add item <type> <submenu> <title> <command>
//popup add submenu <type> <submenu> <title>
//popup clear <type> <submenu>
// 0 1 2 3 4 5 6
char menuname[TEMPLEN];
char basemenuname[TEMPLEN];
char *position;
if(argc<4||argc==5||argc>7) {
Tcl_SetResult(interp,"Usage: popup <command> [2 to 5 arguments] (Global)",TCL_VOLATILE);
return TCL_ERROR;
}
if(!strcasecmp(argv[1],"add")&&!strcasecmp(argv[2],"item")) {
if(!strncmp(argv[3],"main",4)) {
sprintf(menuname,".menu%s%s",argv[3],argv[4]);
} else {
return TCL_OK;
}
TT_EvalF(TT_ARGS,"%s add command -label \"%q\" -command %q",menuname,argv[5],argv[6]);
}
if(!strcasecmp(argv[1],"add")&&!strcasecmp(argv[2],"submenu")) {
if(!strncmp(argv[3],"main",4)) {
sprintf(menuname,".menu%s%s",argv[3],argv[4]);
} else {
return TCL_OK;
}
position=strrchr(menuname,'.');
*position=0;
strcpy(basemenuname,menuname);
*position='.';
TT_EvalF(TT_ARGS,"%s add cascade -label \"%q\" -menu \"%q\"",basemenuname,argv[5],menuname);
TT_EvalF(TT_ARGS,"menu %s",menuname);
}
if(!strcasecmp(argv[1],"clear")) {
if(!strncmp(argv[2],"main",4)) {
sprintf(menuname,".menu%s%s",argv[2],argv[3]);
} else {
return TCL_OK;
}
TT_EvalF(TT_ARGS,"destroy %s",menuname);
TT_EvalF(TT_ARGS,"menu %s",menuname);
}
return TCL_OK;
}
int TT_Proc_previouswindow(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
strcpy(window.pathname,currentwindow);
if((windowp=windows.find(window))) {
if(windowp->index>0) {
TT_EvalF(TT_ARGS,"totop %d",windowp->index-1);
} else {
TT_EvalF(TT_ARGS,"totop %d",windows.lastindex());
}
}
return TCL_OK;
}
int TT_Proc_renamewindow(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
int oldindex;
int newindex;
int reallynewindex;
if(argc!=3) {
Tcl_SetResult(interp,"Usage: renamewindow <pathname> <new name>",TCL_STATIC);
return TCL_ERROR;
}
strcpy(window.pathname,currentwindow);
if(!(windowp=windows.find(window))) {
fprintf(stderr,"Evil Error: The curent window isn't in the window list. This should never happen.\n");
exit(1);
}
oldindex=windowp->index;
strcpy(window.pathname,argv[1]);
if(!(windowp=windows.find(window))) {
Tcl_SetResult(interp,"Usage: renamewindow <pathname> <new name> (Invalid pathname specified.)",TCL_STATIC);
return TCL_ERROR;
}
newindex=windowp->index;
strcpy(window.pathname,windowp->pathname);
window.title=windowp->title;
window.server=windowp->server;
window.dcc=windowp->dcc;
windows.deleteitem(window);
strcpy(window.name,argv[2]);
reallynewindex=windows.insert_ascending(window);
TT_EvalF(TT_ARGS,"QListBox::delete .windowlist %d",newindex);
if(strncmp(".status",argv[1],7)&&strcmp(".main",argv[1])) {
TT_EvalF(TT_ARGS,"QListBox::insert .windowlist %d \"${::dynamic::theme_windowlist_indent}%q\"",reallynewindex,argv[2]);
} else {
TT_EvalF(TT_ARGS,"QListBox::insert .windowlist %d \"%q\"",reallynewindex,argv[2]);
}
if(oldindex==newindex) {
TT_EvalF(TT_ARGS,"QListBox::select .windowlist %d",reallynewindex);
} else {
// Select old selected window again.
strcpy(window.pathname,currentwindow);
if(!(windowp=windows.find(window))) {
fprintf(stderr,"Evil Error: The curent window isn't in the window list. This should never happen.\n");
exit(1);
}
TT_EvalF(TT_ARGS,"QListBox::select .windowlist %d",windowp->index);
}
Tcl_SetResult(interp,strnum(reallynewindex),TCL_VOLATILE);
return TCL_OK;
}
int TT_Proc_say(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
tchan chan;
tchan *chanp;
tquery query;
tquery *queryp;
char argument[TEMPLEN];
char temp[TEMPLEN];
int ok=0;
char *position;
if(argc>3||argc<2) {
Tcl_SetResult(interp,"Usage: say <message> [<target pathname>]",TCL_VOLATILE);
return TCL_ERROR;
}
if(argc==3) {
strcpy(window.pathname,argv[2]);
} else {
strcpy(window.pathname,currentwindow);
}
if(!(windowp=windows.find(window))) {
Tcl_SetResult(interp,"say: Invalid target pathname.",TCL_VOLATILE);
return TCL_ERROR;
}
strcpy(argument,argv[1]);
position=strtok(argument,"\n");
if(!strncmp(window.pathname,".channel",8)) {
strcpy(chan.pathname,window.pathname);
chanp=windowp->server->chanlist.find(chan);
while(position) {
sprintf(temp,"PRIVMSG %s :%s",chanp->name,position);
windowp->server->senddata(temp);
fdisplay("OUTGOING_TEXT",windowp->server->index,2,window.pathname,position);
position=strtok(NULL,"\n");
}
ok=1;
}
if(!strncmp(window.pathname,".query",6)) {
strcpy(query.pathname,window.pathname);
queryp=windowp->server->querylist.find(query);
while(position) {
sprintf(temp,"PRIVMSG %s :%s",queryp->getname(),position);
windowp->server->senddata(temp);
fdisplay("OUTGOING_TEXT",windowp->server->index,2,window.pathname,position);
position=strtok(NULL,"\n");
}
ok=1;
}
if(!strncmp(window.pathname,".chat",5)) {
while(position) {
windowp->dcc->senddata(position);
fdisplay("OUTGOING_TEXT",windowp->server->index,2,window.pathname,position);
position=strtok(NULL,"\n");
}
ok=1;
}
if(ok) return TCL_OK; else {
Tcl_SetResult(interp,"say: Improper say usage. Please use only for query, channel, or chat windows.",TCL_VOLATILE);
return TCL_ERROR;
}
}
int TT_Proc_selectednicks(TT_PROC_ARGS) {
TT_Eval(TT_ARGS,"\
set tempvariable \"\"\n\
if { [string match \".channel*\" [currentwindow]] } {\n\
foreach index [[currentwindow].nicks curselection] {\n\
lappend tempvariable [string trim [join [[currentwindow].nicks get $index $index]] \"+@\"]\n\
}\n\
}\n\
");
Tcl_SetResult(interp,
(char *)TT_Str(TT_ARGS,"set tempvariable"),
TCL_VOLATILE);
return TCL_OK;
}
int TT_Proc_selectedmodenicks(TT_PROC_ARGS) {
TT_Eval(TT_ARGS,"\
set tempvariable \"\"\n\
if { [string match \".channel*\" [currentwindow]] } {\n\
foreach index [[currentwindow].nicks curselection] {\n\
lappend tempvariable [join [[currentwindow].nicks get $index $index]]\b\
}\n\
}\n\
");
Tcl_SetResult(interp,
(char *)TT_Str(TT_ARGS,"set tempvariable"),
TCL_VOLATILE);
return TCL_OK;
}
int TT_Proc_serverindex(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
if(argc!=2) {
Tcl_SetResult(interp,"Usage: serverindex <pathname>",TCL_STATIC);
return TCL_ERROR;
}
strcpy(window.pathname,argv[1]);
Tcl_SetResult(interp,"-1",TCL_VOLATILE);
if((windowp=windows.find(window))) {
if(windowp->server) {
Tcl_SetResult(interp,strnum(windowp->server->index),TCL_VOLATILE);
}
}
return TCL_OK;
}
int TT_Proc_servers(TT_PROC_ARGS) {
twindow *windowp;
string servers;
windows.init_trav();
while((windowp=windows.trav())) {
if(!strncmp(windowp->pathname,".status",7)) {
if(servers.length()) servers+=" ";
servers+=strnum(windowp->server->index);
}
}
Tcl_SetResult(interp,(char *)servers.c_str(),TCL_VOLATILE);
return TCL_OK;
}
int TT_Proc_shutdown(TT_PROC_ARGS) {
twindow *windowp;
char temp[1000];
if(fparse_result) free(fparse_result);
// Clean up format/location hashes
hash_destroy(&formats);
hash_destroy(&activate);
hash_destroy(&locations);
TT_Eval(TT_ARGS,"set ::dynamic::do_rawview 0");
windows.init_trav();
while((windowp=windows.trav())) {
if(!strncmp(windowp->pathname,".status",7)) {
if(windowp->server) {
if(windowp->server->connected) {
//printf("We are here closing sockets.\n");
/*
struct linger lin;
socklen_t linlen=sizeof(lin);
getsockopt(windowp->server->sockfd,SOL_SOCKET,SO_LINGER,&lin,&linlen);
printf("%d and %d\n",lin.l_onoff,lin.l_linger);
*/
TT_EvalF(TT_ARGS,"set ::%d::intentional_disconnect 1",windowp->server->index);
sprintf(temp,"QUIT :%s",TT_Str(TT_ARGS,"set ::dynamic::default_quit"));
windowp->server->senddata(temp);
/*
printf("Pausing for 5 seconds.\n");
sleep(10);
printf("Done!\n");
printf("Shutdown returned: %d\n",shutdown(windowp->server->sockfd,2));
printf("Close returned %d\n",close(windowp->server->sockfd));
*/
shutdown(windowp->server->sockfd,1);
close(windowp->server->sockfd);
}
if(windowp->server->connecting) close(windowp->server->sockfd);
delete windowp->server;
}
}
}
return TCL_OK;
}
int TT_Proc_title(TT_PROC_OBJS) {
int len;
char *arg;
twindow window;
twindow *windowp;
Tcl_Obj *objp;
if(objc>3||objc<2) {
Tcl_SetResult(interp,"Usage: title <pathname> [<text>]",TCL_VOLATILE);
return TCL_ERROR;
}
strcpy(window.pathname,ARGV(1));
if((windowp=windows.find(window))) {
if(objc==2) {
objp=Tcl_NewStringObj((char *)windowp->title.data(),windowp->title.size());
Tcl_SetObjResult(interp,objp);
} else {
arg=Tcl_GetStringFromObj(objv[2],&len);
windowp->title.assign(arg,len);
if(!strcmp(windowp->pathname,currentwindow)) {
TT_EvalF(TT_ARGS,"wm title . %q",arg);
}
}
} else {
Tcl_SetResult(interp,"Usage: title <pathname> [<text>] (Invalid pathname specified.)",TCL_STATIC);
return TCL_ERROR;
}
return TCL_OK;
}
int TT_Proc_totop(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
twindow *windowp2;
string userhostresults;
int n;
int i,i2;
n=atoi(argv[1]);
window.index=n;
windowp=windows.find(window);
if(windowp) {
i=-1;
if(windowp->server) {
i=windowp->server->index;
}
window.index=-1;
strcpy(window.pathname,currentwindow);
if((windowp2=windows.find(window))) {
i2=-1;
if(windowp2->server) {
i2=windowp2->server->index;
}
TT_EvalF(TT_ARGS," if { [info commands ::event_windowchanged]!=\"\" } { event_windowchanged %q %q %d %d %q %q %d %d }",windowp2->pathname,windowp2->name,i2,windowp2->index,windowp->pathname,windowp->name,i,windowp->index);
}
TT_EvalF(TT_ARGS,"wm title . %q",windowp->title.c_str());
}
if(windowp) {
TT_EvalF(TT_ARGS,"raise %s",windowp->pathname);
TT_EvalF(TT_ARGS,"QListBox::colorize .windowlist %d normal", n);
TT_EvalF(TT_ARGS,"QListBox::select .windowlist %d",n);
TT_EvalF(TT_ARGS,"%s.text see end",windowp->pathname);
TT_EvalF(TT_ARGS,"focus %s.entry",windowp->pathname);
strcpy(currentwindow,windowp->pathname);
if(windowp->server) {
TT_EvalF(TT_ARGS,"::template::condis %d",windowp->server->index);
} else {
TT_Eval(TT_ARGS,"::template::condis -1");
}
TT_Eval(TT_ARGS,"update idletasks");
return TCL_OK;
} else {
return TCL_ERROR;
}
}
int TT_Proc_version(TT_PROC_ARGS) {
Tcl_SetResult(interp,VERSION,TCL_VOLATILE);
return TCL_OK;
}
int TT_Proc_windowindex(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
if(argc>2) {
Tcl_SetResult(interp,"Usage: windowindex [<pathname>]",TCL_STATIC);
return TCL_ERROR;
}
if(argc==1) {
strcpy(window.pathname,currentwindow);
} else {
strcpy(window.pathname,argv[1]);
}
Tcl_SetResult(interp,"-1",TCL_STATIC);
if((windowp=windows.find(window))) {
Tcl_SetResult(interp,strnum(windowp->index),TCL_VOLATILE);
} else {
Tcl_SetResult(interp,"Usage: windowindex [<pathname>] (Invalid pathname given.",TCL_STATIC);
return TCL_ERROR;
}
return TCL_OK;
}
int TT_Proc_windowname(TT_PROC_ARGS) {
twindow window;
twindow *windowp;
if(argc>1) {
strcpy(window.pathname,argv[1]);
} else {
strcpy(window.pathname,currentwindow);
}
if((windowp=windows.find(window))) {
Tcl_SetResult(interp,windowp->name,TCL_VOLATILE);
}
return TCL_OK;
}
int TT_Proc_windows(TT_PROC_ARGS) {
Tcl_Obj *listptr;
Tcl_Obj *objptr;
twindow *windowp;
if(argc!=1) {
Tcl_SetResult(interp,"Usage: windows",TCL_STATIC);
return TCL_ERROR;
}
listptr=Tcl_NewListObj(0,0);
windows.init_trav();
while((windowp=windows.trav())) {
objptr=Tcl_NewStringObj(windowp->pathname,strlen(windowp->pathname));
if(Tcl_ListObjAppendElement(interp,listptr,objptr)==TCL_ERROR) return TCL_ERROR;
}
Tcl_SetObjResult(interp,listptr);
return TCL_OK;
}
int TT_Proc_windowtype(TT_PROC_ARGS) {
int x=1;
char temppath[20];
if(argc!=2) {
Tcl_SetResult(interp,"Usage: windowtype <pathname>",TCL_STATIC);
return TCL_ERROR;
}
strcpy(temppath,argv[1]);
while(isalpha(temppath[x])) x++;
temppath[x]=0;
Tcl_SetResult(interp,temppath+1,TCL_VOLATILE);
return TCL_OK;
}
syntax highlighted by Code2HTML, v. 0.9.1