home *** CD-ROM | disk | FTP | other *** search
- /* QAmiTrack.c -- a program to keep a running list of available Amigas. */
-
- #include "QAmiTrackShared.h"
- #include "TrackRexx.h"
- #include "QAmitrack.h"
-
- #include "include:signal.h"
-
- /* our GUI gadget IDs */
- #define GAD_CLIENTLIST 10
- #define GAD_VARLIST 11
- #define GAD_COMMENTSTRING 12
- #define GAD_SERVERSTRING 13
- #define GAD_PORTSTRING 14
- #define GAD_ACTIONCYCLE 15
- #define GAD_LOGLIST 16
-
- /* Menu item IDs */
- #define P_ABOUT 100
- #define P_HIDE 101
- #define P_QUIT 102
- #define O_ENABLED 200
- #define O_CONFIRM 201
- #define O_RAGGED 202
- #define O_BEEPONLOG 203
- #define O_LOG 204
- #define O_LOGNONE 205
- #define O_LOGTERSE 206
- #define O_LOGMODERATE 207
- #define O_LOGVERBOSE 208
- #define O_VIEWHOSTNAME 209
- #define O_VIEWUSERNAME 210
- #define O_VIEWREALNAME 211
- #define O_SORTBYAGE 212
- #define O_SORTBYNAME 213
- #define O_SORTBYCOMMENT 214
- #define O_SORTBYNONE 215
- #define O_LOGVIEWOFF 216
- #define O_LOGVIEW25 217
- #define O_LOGVIEW50 218
- #define O_LOGVIEW75 219
- #define O_LOGVIEWFULL 220
- #define O_REVERTCOMMENT 221
- #define O_CLEARLOGVIEW 222
-
- /* Not in the menus, but... */
- #define O_COMMENT 999
-
- #define Strncat(a,b,c) {strncat(a,b,c); a[c-1] = '\0';}
- #define Strncpy(a,b,c) {strncpy(a,b,c); a[c-1] = '\0';}
-
- /* script callback keywords for rexx script tooltypes */
- const char * rexxScriptNames[] = {
- "LOGONSCRIPT",
- "LOGOFFSCRIPT",
- "UPDATESCRIPT",
- "CONNECTSCRIPT",
- "DISCONNECTSCRIPT",
- "STARTSCRIPT",
- "ENDSCRIPT",
- "SYSMESSAGESCRIPT",
- "DEFAULTSCRIPT"
- };
-
- /* Logging levels */
- #define OUTPUT_NONE 0
- #define OUTPUT_TERSE 1
- #define OUTPUT_MODERATE 2
- #define OUTPUT_VERBOSE 3
-
- /* chords of what to transmit in SendState() */
- #define STATE_REALNAME 0x01
- #define STATE_USERNAME 0x02
- #define STATE_COMMENT 0x04
- #define STATE_WINOPEN 0x08
- #define STATE_ALL 0xFF
-
- /* overridable, compile-time defaults */
- #define DEFAULT_AMITRACK_SERVER "qamitrack.tibb.at"
- #define DEFAULT_AMITRACK_PORT 2957
- #define DEFAULT_AMITRACK_COMMENT ""
- #define DEFAULT_AMITRACK_CXPOPUP "YES"
- #define DEFAULT_AMITRACK_CXPRI 0
- #define DEFAULT_AMITRACK_POPKEY "lcommand shift a"
- #define DEFAULT_AMITRACK_ENABLED "YES"
- #define DEFAULT_AMITRACK_ALLOWMULTIPLE "NO"
- #define DEFAULT_AMITRACK_CONFIRMAPP "YES"
- #define DEFAULT_AMITRACK_RAGGEDTEXT "NO"
- #define DEFAULT_AMITRACK_BEEPONLOG "NO"
- #define DEFAULT_AMITRACK_RECONNECTDELAY 2
- #define DEFAULT_AMITRACK_LOGFILE ""
- #define DEFAULT_AMITRACK_LOGLEVEL "moderate"
- #define DEFAULT_AMITRACK_USERNAME "(anonymous)"
- #define DEFAULT_AMITRACK_VIEWBY "hostname"
- #define DEFAULT_AMITRACK_SORTBY "age"
- #define DEFAULT_AMITRACK_ACCESSTO "#?"
- #define DEFAULT_AMITRACK_LOGVIEWLEVEL "25%"
- #define DEFAULT_AMITRACK_LOGVIEWLENGTH 50
-
- UBYTE ** ttypes = NULL;
- char * rexxScripts[NUM_LOG_ENUMS];
-
- int currentAction = -1;
- BOOL BConfirmAppLaunch, BConnected = FALSE, BBeepOnLog = FALSE;
- BOOL BStartedFromWB = FALSE, BRaggedText;
- int clientListLength = 0, logListLen = 0, nLogLevel;
- int connectDelayLeft = 0, nReconnectDelay; /* nReconnectDelay is in minutes */
- int nViewBy, nSortBy;
-
- int nPort, nNumActions=0, nLastEntryClicked=-1, currentNameLen = -1;
- int timeUnit=60, nUpdateDelay=20; /* Show in minutes, update display three times per minute */
- int nLogViewLevel, maxLogListLen;
- struct CxStuff * CX = NULL;
- struct Client * myInfo = NULL;
- char * szServerName = NULL, * szLogFileName = NULL, * szAccessTo, * origComment = NULL;
- struct QSession * session = NULL;
- char szVersionString[] = "$VER: QAmiTrack 1.92 (Compiled " __DATE__ ")", * pcDisplayVersionString;
- struct TimerStuff * TS = NULL;
- ULONG lastUpdateTime = 0L;
- struct Client * cLastEntryClicked = NULL;
- struct Task * mainTask = NULL;
-
- void Cleanup(void);
- void UpdateWindowTimes(void);
- void InitActions(void); /* NULLs all string pointers */
- void FreeActions(void); /* Frees all string pointers */
-
- int main(int argc, char **argv);
-
- /* Data structures for Gadtools GUI */
- struct Library * WorkbenchBase = NULL;
- struct Library * IconBase = NULL;
- struct Library * GraphicsBase = NULL;
- struct Library * IntuitionBase = NULL;
- struct Library * GadToolsBase = NULL;
- struct Library * DiskFontBase = NULL;
- struct Library * CxBase = NULL;
- struct Library * AMarqueeBase = NULL;
-
- struct RexxHost * rexxHost = NULL;
- struct WindowStuff * TrackWindow = NULL;
- struct Menu * Menu = NULL;
- struct MenuItem * MenuItem = NULL;
-
- struct List clientList, logList;
-
- char * ActionLabels[20], * Actions[20];
-
- /* default GUI settings */
- int nWinLeft = 50;
- int nWinTop = 100;
- int nWinWidth = 520;
- int nWinHeight = 200;
- int nMinWinWidth = 300;
- int nMinWinHeight = 120;
-
- long lLastChangeAt = 0L;
- BOOL BEnabled = TRUE, BAllowMultiple = FALSE;
-
- /* menus */
- struct NewMenu nmMenus[] = {
- NM_TITLE, "Project", NULL, 0L, NULL, NULL,
- NM_ITEM, "About", "?", 0L, NULL, (void *) P_ABOUT,
- NM_ITEM, "Hide", "H", 0L, NULL, (void *) P_HIDE,
- NM_ITEM, NM_BARLABEL, NULL, 0L, NULL, NULL,
- NM_ITEM, "Quit", "Q", 0L, NULL, (void *) P_QUIT,
-
- NM_TITLE, "Options", NULL, 0L, NULL, NULL,
- NM_ITEM, "Enabled", "E", CHECKIT, NULL, (void *) O_ENABLED,
- NM_ITEM, "Confirm", "C", CHECKIT, NULL, (void *) O_CONFIRM,
- NM_ITEM, "Ragged Text", "T", CHECKIT, NULL, (void *) O_RAGGED,
- NM_ITEM, "Beep On Log", "B", CHECKIT, NULL, (void *) O_BEEPONLOG,
-
- NM_ITEM, "Log Level", NULL, NULL, NULL, NULL,
- NM_SUB, "None", "!", CHECKIT, NULL, (void *) O_LOGNONE,
- NM_SUB, "Terse", "@", CHECKIT, NULL, (void *) O_LOGTERSE,
- NM_SUB, "Moderate", "#", CHECKIT, NULL, (void *) O_LOGMODERATE,
- NM_SUB, "Verbose", "$", CHECKIT, NULL, (void *) O_LOGVERBOSE,
-
- NM_ITEM, "View By", NULL, 0L, NULL, NULL,
- NM_SUB, "Hostname", "N", CHECKIT, NULL, (void *) O_VIEWHOSTNAME,
- NM_SUB, "User Name", "U", CHECKIT, NULL, (void *) O_VIEWUSERNAME,
- NM_SUB, "Real Name", "R", CHECKIT, NULL, (void *) O_VIEWREALNAME,
-
- NM_ITEM, "Sort By", NULL, 0L, NULL, NULL,
- NM_SUB, "Age", "A", CHECKIT, NULL, (void *) O_SORTBYAGE,
- NM_SUB, "Name", "M", CHECKIT, NULL, (void *) O_SORTBYNAME,
- NM_SUB, "Comment", "L", CHECKIT, NULL, (void *) O_SORTBYCOMMENT,
- NM_SUB, "None", "G", CHECKIT, NULL, (void *) O_SORTBYNONE,
-
- NM_ITEM, "Log View", NULL, 0L, NULL, NULL,
- NM_SUB, "Off", "1", CHECKIT, NULL, (void *) O_LOGVIEWOFF,
- NM_SUB, "25%", "2", CHECKIT, NULL, (void *) O_LOGVIEW25,
- NM_SUB, "50%", "3", CHECKIT, NULL, (void *) O_LOGVIEW50,
- NM_SUB, "75%", "4", CHECKIT, NULL, (void *) O_LOGVIEW75,
- NM_SUB, "Full", "5", CHECKIT, NULL, (void *) O_LOGVIEWFULL,
-
- NM_ITEM, "Revert Comment",".", 0L, NULL, (void *) O_REVERTCOMMENT,
- NM_ITEM, "Clear Log View","Z", 0L, NULL, (void *) O_CLEARLOGVIEW,
-
- NM_END, NULL, NULL, NULL, NULL, NULL
- };
-
- /* GUI functions */
- struct WindowStuff * SetupTrackWindow(struct WindowStuff *);
- void HandleIDCMP(struct WindowStuff *);
- BOOL UpdateWindow(struct WindowStuff * win, BOOL BFree);
- struct Node * AllocDisplayItem(char * szHostName, ULONG ulIPAddress, ULONG ulHostFieldLen, char * szComment);
- void AttachClientList(struct WindowStuff * win, BOOL BAttach);
- void AttachLogList(struct WindowStuff * win, BOOL BAttach);
- BOOL CreateTrackMenus(struct WindowStuff * win, BOOL BCreate);
-
- /* ------------ Amiga GUI functions -------------------------- */
-
- #define HSPACE 5
- #define VSPACE 5
- #define SERVER_STRING_TEXT "Server:"
- #define PORT_STRING_TEXT "Port:"
- #define COMMENT_STRING_TEXT "Comment:"
-
- void edebug(int i)
- {
- int t = *((int *)i);
- t++;
- }
-
- struct String * NewString(char * string)
- {
- struct String * ret;
- ULONG len = strlen(string)+1;
-
- if (ret = AllocMem(sizeof(struct String) + len, MEMF_ANY))
- {
- ret->bufLen = len;
- ret->buffer = &ret[1];
- strcpy(ret->buffer, string);
- }
- return(ret);
- };
-
- int GetLogViewLevelPercent(ULONG ulCode)
- {
- switch(ulCode)
- {
- case O_LOGVIEWOFF: return 0;
- case O_LOGVIEW25: return 25;
- case O_LOGVIEW50: return 50;
- case O_LOGVIEW75: return 75;
- case O_LOGVIEWFULL: return 100;
- }
- return -1; /* error! */
- }
-
- void FreeString(struct String * s)
- {
- FreeMem(s, sizeof(struct String) + s->bufLen);
- }
-
- /* Returns TRUE and sets s on success, FALSE on failure.
- On failure, old string is still okay. */
- BOOL SetString(struct String ** s, char * newVal)
- {
- struct String * newString;
-
- UNLESS((newVal)&&(newString = NewString(newVal))) return(FALSE);
- FreeString(*s);
- *s = newString;
- return(TRUE);
- }
-
- int GetFieldIDByName(char * name)
- {
- UNLESS(strcmp(name,"comment")) return(O_COMMENT);
- UNLESS(strcmp(name,"hostname")) return(O_VIEWHOSTNAME);
- UNLESS(strcmp(name,"username")) return(O_VIEWUSERNAME);
- UNLESS(strcmp(name,"realname")) return(O_VIEWREALNAME);
- return(0);
- }
-
- struct String ** getField(struct Client * c, char * f)
- {
- UNLESS(strcmp(f,"comment")) return(&c->comment);
- UNLESS(strcmp(f,"username")) return(&c->userName);
- UNLESS(strcmp(f,"realname")) return(&c->realName);
- UNLESS(strcmp(f,"winopen")) return(&c->winOpen);
- return(NULL);
- }
-
-
- void FreeClient(struct Client * c)
- {
- if (c->hostName) FreeString(c->hostName);
- if (c->userName) FreeString(c->userName);
- if (c->realName) FreeString(c->realName);
- if (c->comment) FreeString(c->comment);
- if (c->listString) FreeString(c->listString);
- if (c->winOpen) FreeString(c->winOpen);
- if (cLastEntryClicked == c) cLastEntryClicked = NULL;
- FreeMem(c, sizeof(struct Client));
- }
-
- struct Client * NewClient(char * hostName)
- {
- struct Client * ret;
-
- if (ret = AllocMem(sizeof(struct Client), MEMF_CLEAR))
- {
- if ((ret->firstTime = TRUE) &&
- (ret->hostName = NewString(hostName))&&
- (ret->userName = NewString("anon"))&&
- (ret->realName = NewString("Anonymous"))&& /*********************/
- (ret->winOpen = NewString(""))&& /* Will be set later */
- (ret->comment = NewString(""))&& /*********************/
- (ret->listString = NewString("")))
- {
- ret->node.ln_Name = "";
- ret->timeStamp = time(NULL);
- ret->viewOffset = 0;
- }
- else
- {
- /* Failure! */
- FreeClient(ret);
- ret = NULL;
- }
- }
- return(ret);
- }
-
- /* To tear down, set BCreate==FALSE */
- BOOL CreateTrackMenus(struct WindowStuff * win, BOOL BCreate)
- {
- UNLESS((win)&&(win->vi)) return(FALSE);
-
- UNLESS(BCreate)
- {
- if (Menu)
- {
- ResetMenuStrip(win->win,Menu);
- FreeMenus(Menu);
- Menu = NULL;
- }
- return(FALSE);
- }
-
- /* Create menus */
- UNLESS((Menu = CreateMenus(nmMenus, TAG_DONE)) &&
- (LayoutMenus(Menu, win->vi, TAG_DONE)))
- return(CreateTrackMenus(win, FALSE));
-
- SetMenuStrip(win->win, Menu);
- return(TRUE);
- }
-
- struct String * getDisplayIndexString(struct Client * c)
- {
- switch(nViewBy)
- {
- case O_VIEWHOSTNAME: return c->hostName;
- case O_VIEWUSERNAME: return c->userName;
- case O_VIEWREALNAME: return c->realName;
- }
- printf("getDisplayIndexString: warning, returning NULL!\n");
- return(NULL);
- }
-
- void dateStamp(FILE * f)
- {
- static char temp[100], *t;
-
- sprintf(temp, "%s", ctime(NULL));
- if (t = strchr(temp, '\n')) *t = '\0';
- fprintf(f, "%s ",temp);
- }
-
- void RunRexxScriptsForEvent(int opCode, struct Client * actOn, char * fieldChanged, char * aux1, char * aux2)
- {
- int updateType = fieldChanged ? GetFieldIDByName(fieldChanged) : 0;
- char * rexxScript = rexxScripts[opCode];
-
- if ((opCode == LOG_UPDATE)&&(updateType != O_COMMENT)) return; /* Non-comment types are redundant */
- if (*rexxScript == '\0') rexxScript = rexxScripts[LOG_DEFAULT];
- if (*rexxScript)
- {
- static char temp[256];
- char sep[] = "^";
-
- Strncpy(temp, rexxScript, sizeof(temp));
- Strncat(temp, " ", sizeof(temp));
- Strncat(temp, rexxScriptNames[opCode], sizeof(temp));
-
- switch(opCode)
- {
- case LOG_UPDATE:
- case LOG_LOGON:
- case LOG_LOGOFF:
- Strncat(temp, sep, sizeof(temp));
- Strncat(temp, actOn->hostName->buffer, sizeof(temp));
- Strncat(temp, sep, sizeof(temp));
- Strncat(temp, actOn->userName->buffer, sizeof(temp));
- Strncat(temp, sep, sizeof(temp));
- Strncat(temp, actOn->realName->buffer, sizeof(temp));
- Strncat(temp, sep, sizeof(temp));
- Strncat(temp, (*actOn->winOpen->buffer == 'Y') ? "Y" : "N", sizeof(temp));
- Strncat(temp, sep, sizeof(temp));
- Strncat(temp, actOn->comment->buffer, sizeof(temp));
- break;
-
- case LOG_CONNECT:
- case LOG_DISCONNECT:
- if (szServerName)
- {
- Strncat(temp, sep, sizeof(temp));
- Strncat(temp, szServerName, sizeof(temp));
- }
- break;
-
- case LOG_SYSMESSAGE:
- Strncat(temp, sep, sizeof(temp));
- Strncat(temp, aux1, sizeof(temp));
- Strncat(temp, sep, sizeof(temp));
- Strncat(temp, aux2, sizeof(temp));
- break;
-
- case LOG_START:
- case LOG_END:
- /* No info to append */
- }
-
- if (rexxHost) SendRexxCommand(rexxHost, temp, 0L);
- }
- }
-
-
- void LogEvent(int opCode, struct Client * actOn, char * fieldChanged, char * aux1, char * aux2)
- {
- FILE * logfile;
- char * id = actOn ? getDisplayIndexString(actOn)->buffer : NULL;
- char * comment = actOn ? actOn->comment->buffer : NULL;
- int updateType = fieldChanged ? GetFieldIDByName(fieldChanged) : 0;
-
- if ((id)&&(*id == '\0')) id = actOn->hostName->buffer;
-
- if (nLogLevel == OUTPUT_NONE) return;
- UNLESS((szLogFileName)&&(*szLogFileName)&&(logfile = fopen(szLogFileName, "a"))) return;
-
- switch(nLogLevel)
- {
- case OUTPUT_VERBOSE:
- if (opCode == LOG_START) {dateStamp(logfile); fprintf(logfile, "QAmiTrack begins execution.\n");}
- if (opCode == LOG_END) {dateStamp(logfile); fprintf(logfile, "QAmiTrack exits.\n");}
-
- case OUTPUT_MODERATE:
- if ((opCode == LOG_UPDATE)&&(updateType == O_COMMENT)&&(*comment)) {dateStamp(logfile); fprintf(logfile, "[%s] says: [%s]\n", id, comment);}
- if (opCode == LOG_CONNECT){dateStamp(logfile); fprintf(logfile, "QAmiTrack has connected to server [%s]\n", szServerName);}
-
- case OUTPUT_TERSE:
- if ((BConnected)&&(opCode == LOG_DISCONNECT))
- {
- dateStamp(logfile);
- fprintf(logfile,"The QAmiTrack connection was closed%s%s%s.\n",szServerName,aux1?" [":"",aux1?aux1:"",aux1?"]":"");
- }
- if (opCode == LOG_LOGON)
- {
- dateStamp(logfile); fprintf(logfile, "[%s] is now online.\n",id);
- }
- if (opCode == LOG_LOGOFF) {dateStamp(logfile); fprintf(logfile, "[%s] is no longer on line.\n",id);}
- if (opCode == LOG_SYSMESSAGE) {dateStamp(logfile); fprintf(logfile, "System Message from [%s]: [%s]\n", aux1, aux2);}
-
- case OUTPUT_NONE:
- /* Do nothing--actually this case is never executed anyway */
- }
- fclose(logfile);
- }
-
-
- void LogDisplay(char * msg)
- {
- struct Node * node = AllocMem(sizeof(struct Node)+strlen(msg)+1, MEMF_CLEAR);
-
- if (node)
- {
- node->ln_Name = ((char *)node)+sizeof(struct Node);
- strcpy(node->ln_Name, msg);
- AttachLogList(TrackWindow, FALSE);
- AddTail(&logList, node); logListLen++;
- if (logListLen > maxLogListLen)
- {
- struct Node * top = RemHead(&logList);
- if (top)
- {
- FreeMem(top,sizeof(struct Node)+strlen(top->ln_Name)+1);
- logListLen--;
- }
- }
- AttachLogList(TrackWindow, TRUE);
- if ((TrackWindow)&&(TrackWindow->win)&&(TrackWindow->LogListGadget))
- GT_SetGadgetAttrs(TrackWindow->LogListGadget, TrackWindow->win, NULL, GTLV_Top, logListLen+1, TAG_END);
-
- if (BBeepOnLog) DisplayBeep(NULL);
- }
- else printf("Oops, no memory to allocate Log Display item!\n");
- }
-
- void ClearLogView(void)
- {
- struct Node * next;
-
- AttachLogList(TrackWindow, FALSE);
- while(next = RemHead(&logList)) FreeMem(next,sizeof(struct Node)+strlen(next->ln_Name)+1);
- logListLen = 0;
- AttachLogList(TrackWindow, TRUE);
- }
-
- void DisplayEvent(int opCode, struct Client * actOn, char * fieldChanged, char * aux1, char * aux2)
- {
- char * id = actOn ? getDisplayIndexString(actOn)->buffer : NULL;
- char * comment = actOn ? actOn->comment->buffer : NULL;
- int updateType = fieldChanged ? GetFieldIDByName(fieldChanged) : 0;
- static char temp[512];
-
- if ((id)&&(*id == '\0')) id = actOn->hostName->buffer;
-
- switch(nLogLevel)
- {
- case OUTPUT_VERBOSE:
- if (opCode == LOG_START) LogDisplay("(QAmiTrack begins execution)");
- if (opCode == LOG_END) LogDisplay("(QAmiTrack exits)");
-
- case OUTPUT_MODERATE:
- if (opCode == LOG_CONNECT)
- {
- Strncpy(temp, "QAmiTrack has connected to server [", sizeof(temp));
- Strncat(temp, szServerName, sizeof(temp));
- Strncat(temp, "]", sizeof(temp));
- LogDisplay(temp);
- }
- if (opCode == LOG_LOGON)
- {
- Strncpy(temp, "[", sizeof(temp));
- Strncat(temp, id, sizeof(temp));
- Strncat(temp, "] is now online.", sizeof(temp));
- LogDisplay(temp);
- }
- if (opCode == LOG_LOGOFF)
- {
- Strncpy(temp, "[", sizeof(temp));
- Strncat(temp, id, sizeof(temp));
- Strncat(temp, "] is no longer online.", sizeof(temp));
- LogDisplay(temp);
- }
-
- case OUTPUT_TERSE:
- if ((BConnected)&&(opCode == LOG_DISCONNECT))
- {
- Strncpy(temp, "The QAmiTrack connection was closed.", sizeof(temp));
- if (aux1)
- {
- Strncat(temp, " [", sizeof(temp));
- Strncat(temp, aux1, sizeof(temp));
- Strncat(temp, "]", sizeof(temp));
- }
- LogDisplay(temp);
- }
- if ((opCode == LOG_UPDATE)&&(updateType == O_COMMENT)&&(*comment))
- {
- Strncpy(temp, id, sizeof(temp));
- Strncat(temp, ": ", sizeof(temp));
- Strncat(temp, comment, sizeof(temp));
- LogDisplay(temp);
- }
-
-
- case OUTPUT_NONE:
- if (opCode == LOG_SYSMESSAGE)
- {
- Strncpy(temp, "SYSTEM MESSAGE from [", sizeof(temp));
- Strncat(temp, aux1, sizeof(temp));
- Strncat(temp, "]: ", sizeof(temp));
- Strncat(temp, aux2, sizeof(temp));
- LogDisplay(temp);
- }
- }
- }
-
- void RecordEvent(int opCode, struct Client * actOn, char * fieldChanged, char * aux1, char * aux2)
- {
- LogEvent(opCode, actOn, fieldChanged, aux1, aux2);
- DisplayEvent(opCode, actOn, fieldChanged, aux1, aux2);
- RunRexxScriptsForEvent(opCode, actOn, fieldChanged, aux1, aux2);
- }
-
- void InitActions()
- {
- int i;
-
- for (i=0; i<(sizeof(Actions)/sizeof(char *)); i++)
- Actions[i] = ActionLabels[i] = NULL;
- nNumActions = 0;
- }
-
- void FreeActions()
- {
- int i;
-
- for (i=0; i<(sizeof(Actions)/sizeof(char *)); i++)
- {
- if (Actions[i]) ReplaceAllocedString(&Actions[i], NULL);
- if (ActionLabels[i]) ReplaceAllocedString(&ActionLabels[i], NULL);
- }
- nNumActions = 0;
- }
-
-
- struct Client * GetClientByIndex(int index)
- {
- struct Client * next = (struct Client *) clientList.lh_Head;
-
- while(index--) UNLESS(next = next->node.ln_Succ) return(NULL);
- return(next);
- }
-
- void ListClicked(int index)
- {
- static time_t tLastTimeClicked = (time_t) -1;
- time_t tPreviousTimeClicked = tLastTimeClicked;
-
- tLastTimeClicked = time(NULL);
-
- /* Record which client it was */
- nLastEntryClicked = index;
- cLastEntryClicked = GetClientByIndex(nLastEntryClicked);
-
- if ((index == nLastEntryClicked) &&
- ((tLastTimeClicked-tPreviousTimeClicked) < 2)) (void)DoAction(index, currentAction, BConfirmAppLaunch);
- }
-
-
- struct Client * GetHost(int index)
- {
- struct Client * next = (struct Client *) clientList.lh_Head;
-
- while(index--) {UNLESS(next = next->node.ln_Succ) return(NULL);}
- return(next);
- }
-
- int GetTrackHostByName(char * name)
- {
- struct Node * current;
- int i=0;
-
- current = clientList.lh_Head;
- while(current->ln_Succ)
- {
- struct Client * c = (struct Client *) current;
-
- if (strcmp(c->hostName->buffer, name) == 0) return(i);
- current = current->ln_Succ;
- i++;
- }
- return(-1);
- }
-
- int GetTrackActionByName(char * name)
- {
- int i;
-
- for (i=0;i<nNumActions;i++) if (strcmp(name, ActionLabels[i])==0) return(i);
- return(-1);
- }
-
- /* Allocates a newly malloc'd string with all the replaceMe's replaced with withMe's */
- /* free()'s oldString, or returns it on error or if no changes were made. */
- char * makeSubbedString(char * oldString, char * replaceMe, char * withMe)
- {
- int len = strlen(oldString);
- int oldStringLen = len;
- int replaceMeLen = strlen(replaceMe);
- int withMeLen = strlen(withMe);
- int diff = withMeLen-replaceMeLen;
- int numChanges = 0;
- char * newString, * temp = oldString;
-
- /* Figure out how much extra space we'll need */
- while(temp = strstr(temp, replaceMe))
- {
- len += diff;
- temp += replaceMeLen;
- numChanges++;
- }
- if (numChanges == 0) return(oldString);
- if (newString = malloc(len+1+1)) /* 1 for the NUL, 1 for the debug guard */
- {
- char * nextSub;
-
- temp = oldString;
- *newString = '\0';
-
- /* Place the debug guard here! */
- newString[len+1] = '~'; /* After the NUL, we'll check later to see if this was overridden (which would indicate a BUG!) */
- while(nextSub = strstr(temp, replaceMe))
- {
- char c = *nextSub;
-
- *nextSub = '\0';
- strcat(newString, temp);
- strcat(newString, withMe);
- temp = nextSub + replaceMeLen;
- *nextSub = c;
- }
- strcat(newString, temp);
-
- if (newString[len+1] != '~') (void)MakeReq(NULL, "There's a BUG in QAmiTrack's launching code!", "Better go email Jeremy!");
- free(oldString);
- }
- return(newString ? newString : oldString);
- }
-
- int DoAction(int index, int action, BOOL BConf)
- {
- int result = -2;
- struct Client * target;
- char * s;
- struct Task * thisTask = FindTask(NULL);
- int stackSize = thisTask->tc_SPUpper - thisTask->tc_SPLower;
-
- printf("stackSize = %i\n",stackSize);
- UNLESS((action < nNumActions)&&(action >= 0)&&(target = GetHost(index))) return(-1);
-
- if (BConf)
- {
- /* Do user confirmation */
- const char p1[] = "Okay to connect to ";
- const char p2[] = " using ";
- const char p3[] = "?";
- char * reqText = NULL;
- int reqTextLen = strlen(p1) + strlen(target->hostName->buffer) + strlen(p2) + strlen(ActionLabels[action]) + strlen(p3) + 1;
- BOOL BOk;
-
- UNLESS(reqText = AllocMem(reqTextLen, MEMF_ANY)) return(-1);
- sprintf(reqText, "%s%s%s%s%s",p1,target->hostName->buffer,p2,ActionLabels[action],p3);
- BOk = MakeReq("QAmiTrack Launch Confirmation", reqText, "Connect|Cancel");
- FreeMem(reqText, reqTextLen);
- UNLESS(BOk) return(-2);
- }
-
- if (s = strdup(Actions[action]))
- {
- char timeString1[35], timeString2[35];
-
- sprintf(timeString1,"%i",(time(NULL)-target->timeStamp)/timeUnit);
- sprintf(timeString2,"%i",(time(NULL)-lastUpdateTime)/timeUnit);
-
- s = makeSubbedString(s, "%s", target->hostName->buffer);
- s = makeSubbedString(s, "%h", target->hostName->buffer);
-
- s = makeSubbedString(s, "%u", target->userName->buffer);
- s = makeSubbedString(s, "%U", myInfo->userName->buffer);
-
- s = makeSubbedString(s, "%c", target->comment->buffer);
- s = makeSubbedString(s, "%C", myInfo->comment->buffer);
-
- s = makeSubbedString(s, "%r", target->realName->buffer);
- s = makeSubbedString(s, "%R", myInfo->realName->buffer);
-
- s = makeSubbedString(s, "%l", target->listString->buffer);
-
- s = makeSubbedString(s, "%t", timeString1);
- s = makeSubbedString(s, "%T", timeString2);
-
- s = makeSubbedString(s, "%%", "%");
- s = makeSubbedString(s, "%q", "\"");
-
- if ((result = SystemTags(s,
- SYS_Asynch, TRUE,
- SYS_Input, Open("NIL:",MODE_OLDFILE),
- SYS_Output, NULL,
- NP_StackSize, stackSize,
- TAG_DONE)) == -1)
- MakeReq(NULL,"Error launching program!", NULL);
-
- free(s);
- }
- return(result);
- }
-
-
- int getActionCycleWidth(struct WindowStuff * win)
- {
- int i,len = 0;
- for (i=0; (ActionLabels[i] != NULL); i++)
- {
- int next = TextLength(&win->screen->RastPort, ActionLabels[i], strlen(ActionLabels[i]));
- if (next > len) len = next;
- }
- if (len > 0) len += HSPACE*6; /* For the arrow icon! */
- if (len > (win->win->Width/2)) len = win->win->Width/2; /* Not TOO wide! */
- return(len);
- }
-
-
- /* Updates/reupdates the window on creation or after a size change */
- /* If BFree is TRUE, just deallocate anything that was allocated */
- /* Returns the allocated/deallocated state of the window gadgets */
- BOOL UpdateWindow(struct WindowStuff * win, BOOL BFree)
- {
- struct NewGadget ng;
- struct Gadget * gad;
- int actionLabelLength;
- int leftoverHeight, commentListViewHeight, logListViewHeight;
-
- UNLESS((win)&&(win->screen)) return(FALSE);
-
- /* First deallocate */
- if ((win->win)&&(win->glist)) RemoveGList(win->win, win->glist, -1);
- if (win->glist) {FreeGadgets(win->glist); win->glist = NULL;}
-
- /* Mark all gadgets as free */
- win->CommentListGadget = win->LogListGadget =
- win->ServerString = win->PortString = win->CommentString = NULL;
-
- if (Menu) CreateTrackMenus(win, FALSE);
- if (win->vi) {FreeVisualInfo(win->vi); win->vi = NULL;}
- if (BFree) return(FALSE); /* If we're just freeing, that's all to do */
-
- if (win->win)
- {
- /* erase any gadget imagery */
- EraseRect(win->win->RPort,win->win->BorderLeft, win->win->BorderTop,
- win->win->Width - win->win->BorderRight - 1,
- win->win->Height - win->win->BorderBottom - 1);
- RefreshWindowFrame(win->win);
- }
-
- /* Make sure datestamps are up to date and timer is ticking */
- UpdateWindowTimes();
-
- /* Make everything NULL, etc. */
- memset(&ng, 0, sizeof(ng));
-
- /* Now start allocating */
- UNLESS(win->vi = GetVisualInfo(win->screen,TAG_END)) return(FALSE);
- UNLESS(CreateTrackMenus(win, TRUE)) return(FALSE);
- UNLESS(gad = CreateContext(&win->glist)) return(FALSE);
-
- /* Allocate Server gadget */
- ng.ng_VisualInfo = win->vi;
- ng.ng_TextAttr = &win->font;
- ng.ng_Height = win->font.ta_YSize + VSPACE;
- ng.ng_GadgetText = SERVER_STRING_TEXT;
- ng.ng_LeftEdge += win->screen->WBorLeft + TextLength(&win->screen->RastPort, ng.ng_GadgetText, strlen(ng.ng_GadgetText)) + (HSPACE*3);
- ng.ng_TopEdge = win->screen->WBorTop + win->screen->RastPort.TxHeight + VSPACE;
- ng.ng_Width = ((win->win->Width * 2)/3) - ng.ng_LeftEdge;
- ng.ng_GadgetID = GAD_SERVERSTRING;
- ng.ng_Flags = PLACETEXT_LEFT;
- win->ServerString = gad = CreateGadget(STRING_KIND, gad, &ng, GTST_String, szServerName, GT_Underscore, '_', TAG_END);
-
- /* Allocate Port gadget */
- ng.ng_GadgetText = PORT_STRING_TEXT;
- ng.ng_LeftEdge += ng.ng_Width + TextLength(&win->screen->RastPort, ng.ng_GadgetText, strlen(ng.ng_GadgetText)) + (HSPACE*3);
- ng.ng_Width = win->win->Width - ng.ng_LeftEdge - win->screen->WBorRight - HSPACE;
- ng.ng_GadgetID = GAD_PORTSTRING;
- ng.ng_Flags = PLACETEXT_LEFT;
- win->PortString = gad = CreateGadget(INTEGER_KIND, gad, &ng, GTIN_Number, nPort, GT_Underscore, '_', TAG_END);
-
- /* Calculate the width of the widest action label */
- actionLabelLength = getActionCycleWidth(win);
-
- /* Allocate Comment gadget */
- ng.ng_GadgetText = COMMENT_STRING_TEXT;
- ng.ng_LeftEdge = win->screen->WBorLeft + TextLength(&win->screen->RastPort, ng.ng_GadgetText, strlen(ng.ng_GadgetText)) + (HSPACE*3);
- ng.ng_TopEdge += ng.ng_Height + VSPACE;
- ng.ng_Width = win->win->Width - ng.ng_LeftEdge - win->screen->WBorRight - HSPACE - actionLabelLength - (actionLabelLength ? 2*HSPACE : 0);
- ng.ng_GadgetID = GAD_COMMENTSTRING;
- ng.ng_Flags = PLACETEXT_LEFT;
- win->CommentString = gad = CreateGadget(STRING_KIND, gad, &ng, GTST_String, myInfo->comment->buffer, GTST_MaxChars, 1023, GT_Underscore, '_', TAG_END);
-
- /* Allocate Actions cycle, if we have any actions! */
- if (actionLabelLength > 0)
- {
- ng.ng_GadgetText = NULL;
- ng.ng_LeftEdge += ng.ng_Width + HSPACE;
- ng.ng_Width = actionLabelLength + HSPACE;
- ng.ng_GadgetID = GAD_ACTIONCYCLE;
- win->ActionCycle = gad = CreateGadget(CYCLE_KIND, gad, &ng, GTCY_Labels, ActionLabels, GTCY_Active, currentAction, GT_Underscore, '_', TAG_END);
- }
- else win->ActionCycle = NULL;
-
- /* Allocate ListView */
- ng.ng_GadgetText = NULL;
- ng.ng_TextAttr = &win->fixedfont;
- ng.ng_LeftEdge = win->screen->WBorLeft + HSPACE;
- ng.ng_TopEdge += ng.ng_Height + VSPACE;
- ng.ng_Width = win->win->Width - ng.ng_LeftEdge - win->screen->WBorRight - HSPACE;
-
- /* calculate heights of the two ListView's */
- leftoverHeight = win->win->Height - ng.ng_TopEdge - win->screen->WBorBottom - (VSPACE*2);
- switch(nLogViewLevel)
- {
- case O_LOGVIEWOFF: commentListViewHeight = leftoverHeight; logListViewHeight = 0; break;
- case O_LOGVIEW25: commentListViewHeight = (3*leftoverHeight)/4; logListViewHeight = leftoverHeight/4; break;
- case O_LOGVIEW50: commentListViewHeight = leftoverHeight/2; logListViewHeight = leftoverHeight/2; break;
- case O_LOGVIEW75: commentListViewHeight = leftoverHeight/4; logListViewHeight = (3*leftoverHeight)/4; break;
- case O_LOGVIEWFULL: commentListViewHeight = 0; logListViewHeight = leftoverHeight; break;
- }
-
- ng.ng_Height = commentListViewHeight;
- ng.ng_GadgetID = GAD_CLIENTLIST;
-
- if (ng.ng_Height > 0)
- {
- struct Gadget * tempGad = win->CommentListGadget = CreateGadget(LISTVIEW_KIND, gad, &ng, GTLV_Labels, &clientList, GTLV_ReadOnly, FALSE, TAG_END);
- if (tempGad) gad = tempGad;
- ng.ng_TopEdge += ng.ng_Height;
- }
-
- ng.ng_Height = logListViewHeight;
- ng.ng_GadgetID = GAD_LOGLIST;
- if (ng.ng_Height > 0)
- {
- struct Gadget * tempGad = win->LogListGadget = CreateGadget(LISTVIEW_KIND, gad, &ng, GTLV_Labels, &logList, GTLV_ReadOnly, TRUE, TAG_END);
- if (tempGad) gad = tempGad;
- ng.ng_TopEdge += ng.ng_Height;
- }
-
- /* Attach gadgets to window */
- AddGList(win->win, win->glist, -1, -1, NULL);
- RefreshGList(win->glist, win->win, NULL, -1);
- GT_RefreshWindow(win->win, NULL);
-
- if ((win)&&(win->win)&&(win->LogListGadget))
- GT_SetGadgetAttrs(win->LogListGadget, win->win, NULL, GTLV_Top, logListLen+1, TAG_END);
-
- return(TRUE);
- }
-
-
- void AttachClientList(struct WindowStuff * win, BOOL BAttach)
- {
- if ((win)&&(win->win)&&(win->CommentListGadget))
- {
- GT_SetGadgetAttrs(win->CommentListGadget, win->win, NULL, GTLV_Labels, (BAttach) ? (&clientList) : ((struct List *)(~0)), TAG_END);
- }
- }
-
- void AttachLogList(struct WindowStuff * win, BOOL BAttach)
- {
- if ((win)&&(win->win)&&(win->LogListGadget))
- {
- GT_SetGadgetAttrs(win->LogListGadget, win->win, NULL, GTLV_Labels, (BAttach) ? (&logList) : ((struct List *)(~0)), TAG_END);
- }
- }
-
- int GetNumItems(struct List * list)
- {
- int count = 0;
- struct Node * current = list->lh_Head;
-
- while(current->ln_Succ)
- {
- count++;
- current = current->ln_Succ;
- }
- return(count);
- }
-
- BOOL SendState(ULONG which)
- {
- if (session)
- {
- lastUpdateTime = time(NULL); /* Mark now as the last time we were changed */
-
- /* concatenate the data items together */
- if (which & STATE_REALNAME) QSetOp(session, "realname", myInfo->realName->buffer, myInfo->realName->bufLen);
- if (which & STATE_USERNAME) QSetOp(session, "username", myInfo->userName->buffer, myInfo->userName->bufLen);
- if (which & STATE_WINOPEN) QSetOp(session, "winopen", myInfo->winOpen->buffer, myInfo->winOpen->bufLen);
- if (which & STATE_COMMENT) QSetOp(session, "comment", myInfo->comment->buffer, myInfo->comment->bufLen);
-
- QGo(session, 0L);
- }
- return(session != NULL);
- }
-
- void SetCommentString(struct WindowStuff * win, char * newVal, BOOL BFinal)
- {
- /* Grab and sanitize the new comment */
- SetString(&myInfo->comment, PastSpaces(RemoveUnprintableChars(newVal)));
- if (win) GT_SetGadgetAttrs(win->CommentString, win->win, NULL, GTST_String, myInfo->comment->buffer, TAG_END);
- if (BFinal) SendState(STATE_COMMENT);
- }
-
- /* Frees a malloced() and strduped() Null-terminated string vector */
- void FreeStringArray(char ** array)
- {
- char ** next = array, * This;
-
- while(This = *next) {free(This); next++;}
- free(array);
- }
-
- void SetServerString(struct WindowStuff * win, char * newVal)
- {
- char * szTemp = NULL;
-
- /* Grab and sanitize the new server string */
- ReplaceAllocedString(&szTemp, newVal);
- ReplaceAllocedString(&szServerName, ToLower(PastSpaces(RemoveUnprintableChars(szTemp))));
- ReplaceAllocedString(&szTemp, NULL);
- if (win) GT_SetGadgetAttrs(win->ServerString, win->win, NULL, GTST_String, szServerName, TAG_END);
- SetTrackFlag(CODE_RECONNECT);
- }
-
- void SetPortNumber(struct WindowStuff * win, int nP)
- {
- if (nP <= 0) nP = DEFAULT_AMITRACK_PORT;
- if (win) GT_SetGadgetAttrs(win->PortString, win->win, NULL, GTIN_Number, nP, TAG_END);
- SetTrackFlag(CODE_RECONNECT);
- nPort = nP;
- }
-
-
- void SetCurrentAction(struct WindowStuff * win, char * name)
- {
- int i;
-
- for (i=0; i<nNumActions; i++)
- {
- if (strcmp(name, ActionLabels[i]) == 0)
- {
- SetCurrentActionIndex(win, i);
- return;
- }
- }
- }
-
- void SetCurrentActionIndex(struct WindowStuff * win, int code)
- {
- currentAction = (code >= nNumActions) ? nNumActions-1 : code;
- if ((win)&&(currentAction >= 0))
- GT_SetGadgetAttrs(win->ActionCycle, win->win, NULL,
- GTCY_Active, currentAction,
- GTCY_Labels, ActionLabels,
- TAG_END);
- }
-
- struct Client * FindClientByName(char * hostName)
- {
- struct Client * c = (struct Client *)clientList.lh_Head;
-
- while(c->node.ln_Succ)
- {
- UNLESS(strcmp(hostName, c->hostName->buffer)) return(c);
- c = (struct Client *)c->node.ln_Succ;
- }
- return(NULL);
- }
-
-
- BOOL OutOfOrder(struct Client * c1, struct Client * c2)
- {
- switch(nSortBy)
- {
- case O_SORTBYAGE: return(c1->timeStamp<c2->timeStamp);
- case O_SORTBYNAME: return(stricmp(getDisplayIndexString(c1)->buffer,getDisplayIndexString(c2)->buffer)>0);
- case O_SORTBYCOMMENT: return(stricmp(c1->comment->buffer,c2->comment->buffer)>0);
- default: return(FALSE);
- }
- }
-
- void SortClientList(void)
- {
- int nSwappedThisPass = 1;
- struct Node *current, *past;
-
- if ((clientListLength <= 1)||(nSortBy == O_SORTBYNONE)) return;
-
- while (nSwappedThisPass > 0)
- {
- /* start a pass */
- past = clientList.lh_Head;
- current = past ? past->ln_Succ : NULL;
- nSwappedThisPass = 0; /* start with none recorded */
-
- while ((past)&&(current)&&(current->ln_Succ))
- {
- if (OutOfOrder((struct Client *)past, (struct Client *)current))
- {
- /* Swap the two nodes */
- Remove(past);
- Insert(&clientList, past, current);
- nSwappedThisPass++;
- }
-
- past = current;
- current = current->ln_Succ;
- }
- }
- }
-
- struct Client * AddClient(char * hostName)
- {
- struct Client * newClient;
-
- if (newClient = NewClient(hostName))
- {
- /* Append now node to the clientList */
- struct Client * next = (struct Client *)clientList.lh_Head;
-
- AddTail(&clientList, (struct Node *)newClient);
- clientListLength++;
- }
- return(newClient);
- }
-
- struct String * MakeNewDisplayString(struct Client * c, int nameCol)
- {
- const int dateLen = sizeof("00");
- int stringLen;
- struct String * s, * iString = getDisplayIndexString(c);
-
- if (BRaggedText) nameCol = iString->bufLen;
-
- nameCol += dateLen; /* Prepending chars for the time elapsed! */
- stringLen = nameCol + c->comment->bufLen;
-
- if (s = AllocMem(sizeof(struct String)+stringLen, MEMF_ANY))
- {
- if (c->viewOffset >= (c->comment->bufLen-1)) c->viewOffset = c->comment->bufLen-2;
- if (c->viewOffset < 0) c->viewOffset = 0;
-
- time_t timeDiff = time(NULL)-(c->timeStamp);
- s->bufLen = stringLen;
- s->buffer = (char *)(&s[1]);
- memset(s->buffer, ' ', stringLen);
-
- /* Only display time if it fits! */
- if ((timeDiff/timeUnit) < 100) sprintf(s->buffer,"%2i", timeDiff/timeUnit);
- else sprintf(s->buffer," ");
- s->buffer[2] = (c->winOpen->buffer[0]=='Y') ? '+' : ' ';
- strcpy(s->buffer+dateLen,iString->buffer);
- *(s->buffer+dateLen+iString->bufLen-1)=' ';
- strcpy(s->buffer+nameCol,c->comment->buffer+c->viewOffset);
- }
- return(s);
- }
-
- /* Go through displayed items, reprinting the current elapsed time in each. Reset timer when done! */
- void UpdateWindowTimes(void)
- {
- struct Client * next;
- time_t currentTime = time(NULL);
-
- AttachClientList(TrackWindow, FALSE);
-
- next = (struct Client *)clientList.lh_Head;
- while(next->node.ln_Succ)
- {
- char * buf = next->listString->buffer;
-
- if ((buf)&&(buf[0])&&(buf[1])&&(buf[2])&&(buf[3]))
- {
- time_t timeDiff = currentTime - next->timeStamp;
-
- if ((timeDiff/timeUnit) < 100) sprintf(buf,"%2i", timeDiff/timeUnit);
- else sprintf(buf," ");
- buf[2] = (next->winOpen->buffer[0]=='Y') ? '+' : ' ';
- }
- next = (struct Client *)next->node.ln_Succ;
- }
-
- SortClientList();
- AttachClientList(TrackWindow, TRUE);
- }
-
- BOOL UpdateClientTime(char * path, ULONG secs)
- {
- char * slash;
-
- path++;
- if (slash = strchr(path, '/'))
- {
- struct Client * client;
-
- *slash = '\0';
- if (client = FindClientByName(path))
- {
- client->timeStamp = time(NULL)-secs;
- return(TRUE);
- }
- }
- return(FALSE);
- }
-
- void UpdateClientField(struct Client * modme, char * fieldName, char * newVal)
- {
- struct String ** stringToChange;
- BOOL BLogIt = TRUE;
-
- if (stringToChange = getField(modme, fieldName))
- {
- /* If the new string is the same as the old, no need to update anything! */
- BLogIt = !((*stringToChange)&&((*stringToChange)->buffer)&&
- (newVal)&&(strcmp((*stringToChange)->buffer, newVal) == 0));
-
- SetString(stringToChange, newVal);
- SetString(&modme->listString, ""); /* force update */
- }
- modme->timeStamp = time(NULL);
- modme->viewOffset = 0;
-
- if ((modme->firstTime)&&(GetFieldIDByName(fieldName)==O_COMMENT))
- {
- if (BLogIt) RecordEvent(LOG_LOGON, modme, fieldName, NULL, NULL);
- modme->firstTime=FALSE;
- }
- else if (BLogIt) RecordEvent(LOG_UPDATE, modme, fieldName, NULL, NULL);
- }
-
- void UpdateClientList(struct QMessage * qmsg)
- {
- /* Parse path */
- if (qmsg)
- {
- char * path = qmsg->qm_Path;
- char * data = qmsg->qm_Data;
- char * slash1=NULL, * slash2=NULL;
- char * hostName, * field;
- struct Client * modme;
-
- UNLESS((path)&&(slash1 = strchr(path+1,'/'))&&(slash2 = strchr(slash1+1,'/'))) return;
- hostName = path+1; field = slash2+1;
- *slash1 = *slash2 = '\0'; /* terminate parsed fields */
-
- /* Prepare to modify the ListView */
- AttachClientList(TrackWindow, FALSE);
-
- if (data)
- {
- UNLESS(modme = FindClientByName(hostName))
- {
- ULONG secsSince = time(NULL)-lastUpdateTime;
-
- /* If he's new, send him a message so he knows how long since we've been updated */
- *slash1 = '/'; /* re-concatenate the /hostName/QAmiTrack part */
- (void)QMessageOp(session, path, &secsSince, sizeof(ULONG));
- (void)QGo(session, 0L);
- *slash1 = '\0';
-
- modme = AddClient(hostName);
- }
- if (modme) UpdateClientField(modme, slash2+1, data);
- }
- else
- {
- /* NULL data means he's logging out! */
- if (modme = FindClientByName(hostName))
- {
- RecordEvent(LOG_LOGOFF, modme, NULL, NULL, NULL);
- Remove((struct Node *)modme);
- clientListLength--;
- FreeClient(modme);
- }
- }
- }
-
- {
- int maxNameLen=0;
- BOOL BReformat = FALSE;
- struct Client * next;
-
- AttachClientList(TrackWindow, FALSE);
-
- /* Recalculate the display strings */
- next = (struct Client *)clientList.lh_Head;
- while(next->node.ln_Succ)
- {
- int len = getDisplayIndexString(next)->bufLen;
- if (maxNameLen < len) maxNameLen = len;
- next = next->node.ln_Succ;
- }
- BReformat = (maxNameLen != currentNameLen);
- currentNameLen = maxNameLen;
-
- /* Now regenerate all listStrings */
- next = (struct Client *)clientList.lh_Head;
- while(next->node.ln_Succ)
- {
- struct String * oldString = next->listString;
-
- if ((BReformat)||(*(oldString->buffer)=='\0'))
- {
- struct String * newString;
-
- if (newString = MakeNewDisplayString(next, maxNameLen))
- {
- if (oldString) FreeString(oldString);
- next->listString = newString;
- next->node.ln_Name = next->listString->buffer;
- }
- }
- next = (struct Client *)next->node.ln_Succ;
- }
-
- SortClientList();
- }
- AttachClientList(TrackWindow, TRUE);
- }
-
-
- void ScrollClient(struct Client * c, int scrollBy)
- {
- struct String * newString;
-
- if (newString = NewString(""))
- {
- c->viewOffset += scrollBy;
- if (c->viewOffset < 0) c->viewOffset = 0;
-
- AttachClientList(TrackWindow, FALSE); /* avoid dangling pointer */
-
- /* Put the client in a state where it will be updated! */
- FreeString(c->listString);
- c->listString = newString;
-
- UpdateClientList(NULL); /* list will be reattached to window here */
- }
- }
-
-
- void SetViewBy(ULONG ulItemCode)
- {
- if (nViewBy != ulItemCode)
- {
- nViewBy = ulItemCode;
- currentNameLen = -1; /* Force redraw of whole list */
- UpdateClientList(NULL);
- }
- }
-
- void SetSortBy(ULONG ulItemCode)
- {
- if (nSortBy != ulItemCode)
- {
- nSortBy = ulItemCode;
- currentNameLen = -1; /* Force redraw of whole list */
- UpdateClientList(NULL);
- }
- }
-
- BOOL SetLogViewLevel(ULONG ulItemCode)
- {
- if (nLogViewLevel != ulItemCode)
- {
- nLogViewLevel = ulItemCode;
- return(TRUE);
- }
- return(FALSE);
- }
-
- /* Returns any additional action flags that we want set */
- void HandleIDCMP(struct WindowStuff * win)
- {
- struct IntuiMessage *message;
- ULONG class, code, qual, ulItemCode, id;
- struct Gadget * gad;
- struct MenuItem * mItem;
-
- if (win == NULL) SetTrackFlag(CODE_QUIT);
-
- /* Examine pending messages */
- while (message = (struct IntuiMessage *)GT_GetIMsg(win->win->UserPort))
- {
- class = message->Class; /* extract needed info from message */
- code = message->Code;
- qual = message->Qualifier;
- gad = (struct Gadget *) (message->IAddress);
-
- /* tell Intuition we got the message */
- GT_ReplyIMsg(message);
-
- /* see what events occured, take correct action */
- switch(class)
- {
- case IDCMP_CLOSEWINDOW:
- SetTrackFlag(CODE_HIDE);
- break;
-
- case IDCMP_NEWSIZE:
- {
- char temp[50];
- UpdateWindow(win,FALSE);
- sprintf(temp, "Resize: X=%i, Y=%i, W=%i, H=%i",
- win->win->LeftEdge, win->win->TopEdge,
- win->win->Width, win->win->Height);
- StatMessage(temp);
- }
- break;
-
- case IDCMP_INTUITICKS:
- break;
-
- case IDCMP_MOUSEBUTTONS:
- break;
-
- case IDCMP_VANILLAKEY:
- {
- char buf[2];
-
- buf[0] = code; buf[1] = '\0';
- SetCommentString(win, buf, FALSE);
- ((struct StringInfo*)win->CommentString->SpecialInfo)->BufferPos = 1; /* hack the cursor over to the right, dammit! */
- ActivateGadget(win->CommentString, win->win, NULL);
- }
- break;
-
- case IDCMP_RAWKEY:
- if (cLastEntryClicked)
- {
- switch(code)
- {
- case 'L': ScrollClient(cLastEntryClicked, -5000); break;
- case 'M': ScrollClient(cLastEntryClicked, 10); break;
- case 'N': ScrollClient(cLastEntryClicked, 1); break;
- case 'O': ScrollClient(cLastEntryClicked, -1); break;
- }
- }
- break;
-
- case IDCMP_GADGETUP:
- switch(gad ? gad->GadgetID : -1)
- {
- case GAD_CLIENTLIST: ListClicked(code); break;
- case GAD_COMMENTSTRING: SetCommentString(TrackWindow, ((struct StringInfo*)win->CommentString->SpecialInfo)->Buffer, TRUE); break;
- case GAD_SERVERSTRING: SetServerString(TrackWindow, ((struct StringInfo*)win->ServerString->SpecialInfo)->Buffer); break;
- case GAD_PORTSTRING: SetPortNumber(TrackWindow, ((struct StringInfo*)win->PortString->SpecialInfo)->LongInt); break;
- case GAD_ACTIONCYCLE: SetCurrentActionIndex(TrackWindow,code); break;
- default: printf("HandleICMP: unknown gadget ID %i\n", id); break;
- }
- break;
-
- case IDCMP_MENUPICK:
- {
- BOOL BUpdateWin = FALSE;
-
- while(code != MENUNULL)
- {
- char szMessage[150];
- mItem = ItemAddress( Menu, code );
-
- ulItemCode = (ULONG) GTMENUITEM_USERDATA(mItem);
- switch(ulItemCode)
- {
- case P_HIDE:
- SetTrackFlag(CODE_HIDE);
- break;
-
- case P_ABOUT:
- sprintf(szMessage,"%s\nby Jeremy Friesner\njfriesne@ucsd.edu\nCompiled: %s",
- pcDisplayVersionString,__DATE__);
- MakeReq(NULL,szMessage,"Not Bad");
- break;
-
- case P_QUIT:
- SetTrackFlag(CODE_QUIT);
- break;
-
- case O_CONFIRM:
- BConfirmAppLaunch = BConfirmAppLaunch ? FALSE : TRUE;
- break;
-
- case O_RAGGED:
- BRaggedText = !BRaggedText;
- currentNameLen = -1; /* Force re-creation of display list */
- UpdateClientList(NULL);
- break;
-
- case O_BEEPONLOG:
- BBeepOnLog = !BBeepOnLog;
- break;
-
- case O_ENABLED:
- SetTrackFlag(BEnabled ? CODE_DISABLE : CODE_ENABLE);
- break;
-
- case O_LOGNONE: nLogLevel = OUTPUT_NONE; break;
- case O_LOGTERSE: nLogLevel = OUTPUT_TERSE; break;
- case O_LOGMODERATE: nLogLevel = OUTPUT_MODERATE; break;
- case O_LOGVERBOSE: nLogLevel = OUTPUT_VERBOSE; break;
-
- case O_VIEWUSERNAME: case O_VIEWHOSTNAME: case O_VIEWREALNAME:
- SetViewBy(ulItemCode);
- break;
-
- case O_SORTBYAGE: case O_SORTBYNAME: case O_SORTBYCOMMENT: case O_SORTBYNONE:
- SetSortBy(ulItemCode);
- break;
-
- case O_LOGVIEWOFF: case O_LOGVIEW25: case O_LOGVIEW50: case O_LOGVIEW75: case O_LOGVIEWFULL:
- BUpdateWin = (ulItemCode != nLogViewLevel);
- SetLogViewLevel(ulItemCode);
- break;
-
- case O_CLEARLOGVIEW:
- ClearLogView();
- break;
-
- case O_REVERTCOMMENT:
- SetCommentString(TrackWindow, origComment, TRUE);
- break;
- }
- code = mItem->NextSelect;
- }
-
- if (BUpdateWin) UpdateWindow(win, FALSE);
- }
- break;
-
- case IDCMP_REFRESHWINDOW:
- GT_BeginRefresh(win->win);
- GT_EndRefresh(win->win, TRUE);
- nWinWidth = win->win->Width;
- nWinHeight = win->win->Height;
- nWinLeft = win->win->LeftEdge;
- nWinTop = win->win->TopEdge;
- break;
-
- default:
- printf("handleIDCMP: bad class %lu\n",class);
- break;
- }
- }
- }
-
- struct CxStuff * SetupCxStuff(struct CxStuff * cx, int pri, char * hotkey)
- {
- if (cx)
- {
- if (cx->name) FreeMem(cx->name, strlen(cx->name)+1);
- if (cx->broker) DeleteCxObjAll(cx->broker);
- if (cx->port)
- {
- /* deallocate cx */
- CxMsg * msg;
-
- while(msg = (CxMsg *)GetMsg(cx->port)) ReplyMsg((struct Message *)msg);
- DeletePort(cx->port);
- }
- FreeMem(cx, sizeof(struct CxStuff));
- return(NULL);
- }
- else
- {
- char name[200];
- CxObj * filter;
-
- /* allocate and return a new cx */
- UNLESS(cx = AllocMem(sizeof(struct CxStuff), MEMF_CLEAR)) return(NULL);
- UNLESS(cx->port = CreateMsgPort()) return(SetupCxStuff(cx,0,NULL));
-
- if (BAllowMultiple) sprintf(name,"QAmiTrack %lu",time(NULL));
- else strcpy(name,"QAmiTrack");
-
- UNLESS(cx->name = AllocMem(strlen(name)+1, MEMF_ANY)) return(SetupCxStuff(cx,0,NULL));
- strcpy(cx->name, name);
-
- cx->nb.nb_Version = NB_VERSION;
- cx->nb.nb_Name = cx->name;
- cx->nb.nb_Title = pcDisplayVersionString;
- cx->nb.nb_Descr = "Lists other Amigas on the 'net";
- cx->nb.nb_Unique = NBU_UNIQUE | NBU_NOTIFY;
- cx->nb.nb_Flags = COF_SHOW_HIDE; /* We'll have a window available */
- cx->nb.nb_Pri = pri;
- cx->nb.nb_Port = cx->port;
- cx->nb.nb_ReservedChannel = 0;
-
- UNLESS(cx->broker = CxBroker(&cx->nb, NULL)) return(SetupCxStuff(cx,0,NULL));
- if ((hotkey)&&(filter=CxFilter(hotkey)))
- {
- CxObj *sender;
-
- AttachCxObj(cx->broker, filter);
- if (sender = CxSender(cx->port, EVT_HOTKEY))
- {
- CxObj *translate;
-
- AttachCxObj(filter,sender);
- if (translate = CxTranslate(NULL)) AttachCxObj(filter, translate);
- }
- }
-
- ActivateCxObj(cx->broker, 1L); /* Makes us "active" -- receiving messages */
- if (BEnabled == FALSE) ActivateCxObj(cx->broker, 0L); /* Now disable it */
- return(cx);
- }
- }
-
- struct WindowStuff * SetupTrackWindow(struct WindowStuff * win)
- {
- if (win)
- {
- /* Free the window */
- UpdateWindow(win,TRUE); /* Free all the gadgets */
- if (win->fontdata) CloseFont(win->fontdata);
- if (win->fixedfontdata) CloseFont(win->fixedfontdata);
- if (win->win)
- {
- nWinTop = win->win->TopEdge;
- nWinLeft = win->win->LeftEdge;
- CloseWindow(win->win);
- }
- if (win->screen) UnlockPubScreen(NULL,win->screen);
-
- FreeMem(win,sizeof(struct WindowStuff));
- return(NULL);
- }
- else
- {
- UNLESS(win = AllocMem(sizeof(struct WindowStuff), MEMF_CLEAR)) return(NULL);
-
- /* Find the default public screen */
- UNLESS(win->screen = LockPubScreen(NULL)) return(SetupTrackWindow(win));
-
- AskFont(&win->screen->RastPort, &win->font);
- UNLESS(win->fontdata = OpenDiskFont(&win->font)) return(SetupTrackWindow(win));
-
- nMinWinHeight = win->screen->WBorTop + win->screen->RastPort.TxHeight + VSPACE + 3*(win->font.ta_YSize + VSPACE + VSPACE) + win->screen->WBorBottom + VSPACE;
- nMinWinWidth = win->screen->WBorLeft + (HSPACE * 25) + win->screen->WBorRight;
-
- if (nWinWidth < nMinWinWidth) nWinWidth = nMinWinWidth;
- if (nWinHeight < nMinWinHeight) nWinHeight= nMinWinHeight;
-
- /* Open the window */
- UNLESS(win->win = OpenWindowTags(NULL,
- WA_Left, nWinLeft,
- WA_Top, nWinTop,
- WA_Width, nWinWidth,
- WA_Height, nWinHeight,
- WA_MinWidth, nMinWinWidth,
- WA_MinHeight, nMinWinHeight,
- WA_PubScreen, win->screen,
- WA_PubScreenFallBack, TRUE,
- WA_MaxWidth, -1,
- WA_MaxHeight, -1,
- WA_Title, pcDisplayVersionString,
- WA_CloseGadget, TRUE,
- WA_DepthGadget, TRUE,
- WA_SizeGadget, TRUE,
- WA_Activate, TRUE,
- WA_DragBar, TRUE,
- WA_SizeBBottom, TRUE,
- WA_Flags, WFLG_NEWLOOKMENUS,
- WA_IDCMP, IDCMP_REFRESHWINDOW | IDCMP_CLOSEWINDOW |
- IDCMP_MENUPICK | IDCMP_NEWSIZE | IDCMP_VANILLAKEY |
- IDCMP_RAWKEY | BUTTONIDCMP | LISTVIEWIDCMP |
- CYCLEIDCMP | STRINGIDCMP,
- TAG_DONE)) return(SetupTrackWindow(win));
-
- AskFont(win->win->RPort, &win->fixedfont);
- UNLESS(win->fixedfontdata = OpenDiskFont(&win->fixedfont)) return(SetupTrackWindow(win));
- UNLESS(UpdateWindow(win,FALSE)) return(SetupTrackWindow(win));
- return(win);
- }
- }
-
- void debug(int n)
- {
- printf("enter debug %i ... ",n); fflush(stdout);
- Delay(50);
- printf("continuing.\n"); fflush(stdout);
- }
-
- VOID wbmain(struct WBStartup *wbargv)
- {
- BStartedFromWB = TRUE;
- main(0,wbargv);
- }
-
- /* return TRUE iff the string represents the boolean value true */
- BOOL ParseBool(char * string)
- {
- char temp[100];
-
- strncpy(temp,string,sizeof(temp));
- temp[99]=0;
-
- ToLower(temp);
-
- return(
- (*temp=='\0') || /* then it's just KEYWORD, so yes, right? */
- (strcmp("true",temp) == 0) ||
- (strcmp("yes",temp) == 0) ||
- (strcmp("1",temp) == 0)); /* Anyone who specifies 1 for true is a weenie! */
- }
-
-
- int ParseOutputLevel(char * keyword)
- {
- ToLower(keyword);
- UNLESS(strcmp(keyword, "terse")) return OUTPUT_TERSE;
- UNLESS(strcmp(keyword, "moderate")) return OUTPUT_MODERATE;
- UNLESS(strcmp(keyword, "verbose")) return OUTPUT_VERBOSE;
- return OUTPUT_NONE; /* default */
- }
-
- int ParseLogViewLevel(char * keyword)
- {
- ToLower(keyword);
- UNLESS(strcmp(keyword, "off")) return O_LOGVIEWOFF;
- UNLESS(strncmp(keyword, "0", 1)) return O_LOGVIEWOFF;
- UNLESS(strncmp(keyword, "25", 2)) return O_LOGVIEW25;
- UNLESS(strncmp(keyword, "50", 2)) return O_LOGVIEW50;
- UNLESS(strncmp(keyword, "75", 2)) return O_LOGVIEW75;
- UNLESS(strncmp(keyword, "100",3)) return O_LOGVIEWFULL;
- UNLESS(strcmp(keyword, "full")) return O_LOGVIEWFULL;
- return O_LOGVIEWOFF; /* default */
- }
-
- int ParseViewBy(char * keyword)
- {
- ToLower(keyword);
-
- UNLESS(strcmp(keyword, "username")) return O_VIEWUSERNAME;
- UNLESS(strcmp(keyword, "realname")) return O_VIEWREALNAME;
- return O_VIEWHOSTNAME; /* default */
- }
-
- int ParseSortBy(char * keyword)
- {
- ToLower(keyword);
-
- UNLESS(strcmp(keyword, "age")) return O_SORTBYAGE;
- UNLESS(strcmp(keyword, "name")) return O_SORTBYNAME;
- UNLESS(strcmp(keyword, "comment")) return O_SORTBYCOMMENT;
- UNLESS(strcmp(keyword, "none")) return O_SORTBYNONE;
-
- return O_SORTBYAGE; /* default */
- }
-
- char * GetViewByName(int k)
- {
- switch(k)
- {
- case O_VIEWUSERNAME: return("username");
- case O_VIEWHOSTNAME: return("hostname");
- case O_VIEWREALNAME: return("realname");
- default: return("error");
- }
- }
-
- char * GetSortByName(int k)
- {
- switch(k)
- {
- case O_SORTBYAGE: return("age");
- case O_SORTBYNAME: return("name");
- case O_SORTBYCOMMENT: return("comment");
- case O_SORTBYNONE: return("nothing");
- default: return("error");
- }
- }
-
- char * GetOutputLevelName(int id)
- {
- switch(id)
- {
- case OUTPUT_NONE: return("none");
- case OUTPUT_TERSE: return("terse");
- case OUTPUT_MODERATE: return("moderate");
- case OUTPUT_VERBOSE: return("verbose");
- default: return("error");
- }
- }
-
- void SetLogViewLength(int numLines)
- {
- if (numLines >= 0)
- {
- AttachLogList(TrackWindow, FALSE);
- while(logListLen > numLines)
- {
- struct Node * top = RemHead(&logList);
- if (top)
- {
- FreeMem(top,sizeof(struct Node)+strlen(top->ln_Name)+1);
- logListLen--;
- }
- }
- AttachLogList(TrackWindow, TRUE);
- maxLogListLen = numLines;
- }
- }
-
- void SetRexxScript(int which, char * name)
- {
- if ((which >= 0)&&(which < NUM_LOG_ENUMS))
- {
- char * Old = rexxScripts[which];
- char * New = strdup(name);
-
- if (New)
- {
- rexxScripts[which] = New;
- if (Old) free(Old);
- }
- }
- }
-
- void FreeClientList(void)
- {
- struct Client * next;
-
- while(next = (struct Client *) RemHead(&clientList)) FreeClient(next);
- clientListLength = 0;
- }
-
- /* Always called when AmiTrack exits, does any necessary cleanup */
- void Cleanup(void)
- {
- int i;
-
- RecordEvent(LOG_END, NULL, NULL, NULL, NULL);
-
- ClearLogView();
-
- for (i=0; i<NUM_LOG_ENUMS; i++) if (rexxScripts[i]) free(rexxScripts[i]);
-
- if (szLogFileName) free(szLogFileName);
- if (TS) SetupTimer(TS);
- if (rexxHost) CloseDownARexxHost(rexxHost);
- if (CX) SetupCxStuff(CX,0,NULL);
- if (ttypes) ArgArrayDone();
- if (TrackWindow) SetupTrackWindow(TrackWindow);
- if (session) QFreeSession(session);
- if (myInfo) FreeClient(myInfo);
-
- FreeActions();
- FreeClientList();
- ReplaceAllocedString(&szServerName, NULL);
-
- if (AMarqueeBase) CloseLibrary(AMarqueeBase);
- if (DiskFontBase) CloseLibrary(DiskFontBase);
- if (GadToolsBase) CloseLibrary(GadToolsBase);
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- if (GraphicsBase) CloseLibrary(GraphicsBase);
- if (WorkbenchBase) CloseLibrary(WorkbenchBase);
- if (IconBase) CloseLibrary(IconBase);
- if (CxBase) CloseLibrary(CxBase);
- }
-
- void Disconnect(char * optStat)
- {
- if (session)
- {
- QFreeSession(session);
- session = NULL;
- RecordEvent(LOG_DISCONNECT, NULL, NULL, optStat, NULL);
- BConnected = FALSE;
- }
- if (optStat) StatMessage(optStat);
-
- /* Clear the client list! */
- AttachClientList(TrackWindow, FALSE);
- FreeClientList();
- AttachClientList(TrackWindow, TRUE);
- }
-
- void Reconnect(void)
- {
- char szMessage[400];
- char szInterest[] = "/#?/QAmiTrack/(comment|username|realname|winopen)";
- int maxFieldLen = 1024;
-
- UNLESS(BEnabled) return;
-
- Disconnect(NULL);
- UNLESS(*szServerName)
- {
- StatMessage("Can't connect, no server name given.");
- return;
- }
-
- if (session = QNewSessionAsync(szServerName, nPort, "QAmiTrack"))
- {
- sprintf(szMessage,"Connecting to [%s:%i]",szServerName,nPort);
- StatMessage(szMessage);
-
- /* these won't get processed until the connection is ready! */
- sprintf(szMessage,"/%s/QAmiTrack", szAccessTo);
- UNLESS((QSetMessageAccessOp(session, "/#?/QAmiTrack", sizeof(ULONG))) &&
- (QSetAccessOp(session, szMessage)) &&
- (QRequestPrivilegesOp(session, QPRIV_GETSYSMESSAGES)) &&
- (QGetOp(session, szInterest, maxFieldLen)) &&
- (QSubscribeOp(session, szInterest, maxFieldLen)) &&
- (SendState(STATE_ALL)) &&
- (QGo(session, 0L)))
- {
- sprintf(szMessage, "Couldn't log in to server [%s:%i]",szServerName,nPort);
- Disconnect(szMessage);
- }
- }
- else
- {
- if (szServerName)
- {
- sprintf(szMessage,"Couldn't connect to %s:%i",szServerName, nPort);
- StatMessage(szMessage);
- }
- }
- }
-
-
- void StatMessage(char * message)
- {
- static char szMessage[100] = "AmiTrack ready.";
-
- if (message) strncpy(szMessage,message,sizeof(szMessage));
- szMessage[99] = '\0';
-
- if ((TrackWindow)&&(TrackWindow->win))
- SetWindowTitles(TrackWindow->win, szMessage, (char *)~0);
- }
-
- #define UPDATEMENUFLAG(item, variable, flag) {if (variable) item->Flags |= flag; else item->Flags &= ~(flag);}
- void SetMenuValues(void)
- {
- struct Menu *currentMenu = Menu; /* Project Menu */
- struct MenuItem *currentItem, *currentSub;
-
- UNLESS(TrackWindow) return;
- ClearMenuStrip(TrackWindow->win);
-
- currentMenu = currentMenu->NextMenu; /* Options menu */
-
- currentItem = currentMenu->FirstItem; /* Enabled */
- UPDATEMENUFLAG(currentItem, BEnabled, CHECKED);
-
- currentItem = currentItem->NextItem; /* Confirm */
- UPDATEMENUFLAG(currentItem, BConfirmAppLaunch, CHECKED);
- UPDATEMENUFLAG(currentItem, Actions[0], ITEMENABLED);
-
- currentItem = currentItem->NextItem; /* Ragged Text */
- UPDATEMENUFLAG(currentItem, BRaggedText, CHECKED);
-
- currentItem = currentItem->NextItem; /* Beep On Log */
- UPDATEMENUFLAG(currentItem, BBeepOnLog, CHECKED);
-
- currentItem = currentItem->NextItem; /* Log Events */
-
- currentSub = currentItem->SubItem; /* Log None */
- UPDATEMENUFLAG(currentSub, nLogLevel==OUTPUT_NONE, CHECKED);
-
- currentSub = currentSub->NextItem; /* Log Terse */
- UPDATEMENUFLAG(currentSub, nLogLevel==OUTPUT_TERSE, CHECKED);
-
- currentSub = currentSub->NextItem; /* Log Moderate */
- UPDATEMENUFLAG(currentSub, nLogLevel==OUTPUT_MODERATE, CHECKED);
-
- currentSub = currentSub->NextItem; /* Log Verbose */
- UPDATEMENUFLAG(currentSub, nLogLevel==OUTPUT_VERBOSE, CHECKED);
-
- currentItem = currentItem->NextItem; /* View By... */
-
- currentSub = currentItem->SubItem; /* Host Name */
- UPDATEMENUFLAG(currentSub, (nViewBy==O_VIEWHOSTNAME), CHECKED);
-
- currentSub = currentSub->NextItem; /* User Name */
- UPDATEMENUFLAG(currentSub, (nViewBy==O_VIEWUSERNAME), CHECKED);
-
- currentSub = currentSub->NextItem; /* Real Name */
- UPDATEMENUFLAG(currentSub, (nViewBy==O_VIEWREALNAME), CHECKED);
-
- currentItem = currentItem->NextItem; /* Sort By... */
-
- currentSub = currentItem->SubItem; /* Age */
- UPDATEMENUFLAG(currentSub, (nSortBy==O_SORTBYAGE), CHECKED);
-
- currentSub = currentSub->NextItem; /* Name */
- UPDATEMENUFLAG(currentSub, (nSortBy==O_SORTBYNAME), CHECKED);
-
- currentSub = currentSub->NextItem; /* Comment */
- UPDATEMENUFLAG(currentSub, (nSortBy==O_SORTBYCOMMENT), CHECKED);
-
- currentSub = currentSub->NextItem; /* None */
- UPDATEMENUFLAG(currentSub, (nSortBy==O_SORTBYNONE), CHECKED);
-
- currentItem = currentItem->NextItem; /* Log View... */
-
- currentSub = currentItem->SubItem; /* Off */
- UPDATEMENUFLAG(currentSub, (nLogViewLevel==O_LOGVIEWOFF), CHECKED);
-
- currentSub = currentSub->NextItem; /* 25% */
- UPDATEMENUFLAG(currentSub, (nLogViewLevel==O_LOGVIEW25), CHECKED);
-
- currentSub = currentSub->NextItem; /* 50% */
- UPDATEMENUFLAG(currentSub, (nLogViewLevel==O_LOGVIEW50), CHECKED);
-
- currentSub = currentSub->NextItem; /* 75% */
- UPDATEMENUFLAG(currentSub, (nLogViewLevel==O_LOGVIEW75), CHECKED);
-
- currentSub = currentSub->NextItem; /* Full */
- UPDATEMENUFLAG(currentSub, (nLogViewLevel==O_LOGVIEWFULL), CHECKED);
-
- ResetMenuStrip(TrackWindow->win, Menu);
- return;
- }
-
- /* accepts a command string of the following format:
-
- "NAME,COMMAND"
-
- To insert, update, or delete an action. e.g.
-
- "AmiPhone,sys:utilities/AmiPhone CONNECT=%s"
-
- Would add a command named AmiPhone to the cycle gadget.
-
- To delete an action, specify the name without a command. e.g.
-
- "AmiPhone"
-
- Returns the index of the new (or removed) command, or -1 if
- there was an error (out of memory or all 20 spots used)
-
- */
- int UpdateActions(struct WindowStuff * win, char * string)
- {
- int prevGadWidth;
- char name[75] = "", command[300] = "", *pcTemp;
- int index = -1, i;
-
- if (win) prevGadWidth = getActionCycleWidth(win);
-
- if (pcTemp = strchr(string, ',')) *pcTemp = '\0';
- strncpy(name, string, sizeof(name));
- if (pcTemp)
- {
- *pcTemp = ','; pcTemp++;
- strncpy(command, pcTemp, sizeof(command));
- }
-
- /* Check current index to see if the item is already present */
- for (i=0; ((ActionLabels[i])&&(i<20)); i++)
- {
- if (strcmp(name, ActionLabels[i]) == 0)
- {
- index = i;
- break;
- }
- }
-
- if (index >= 0)
- {
- /* Replace/Delete existing command */
- if (command[0]) ReplaceAllocedString(&Actions[index], command);
- else
- {
- /* delete this entry and move the following entries back one! */
- ReplaceAllocedString(&ActionLabels[index], NULL);
- ReplaceAllocedString(&Actions[index], NULL);
- for (int i=index; i<19; i++)
- {
- ActionLabels[i] = ActionLabels[i+1];
- Actions[i] = Actions[i+1];
- }
- Actions[19] = ActionLabels[19] = NULL;
- nNumActions--;
-
- /* Shrink cycle gadget if necessary */
- if ((win)&&(getActionCycleWidth(win) < prevGadWidth)) UpdateWindow(win, FALSE);
- SetCurrentActionIndex(win, currentAction);
- return(index);
- }
- }
- else
- {
- /* Add new command */
- if ((name[0])&&(command[0]))
- {
- for (i=0; i<20; i++)
- {
- if (ActionLabels[i] == NULL)
- {
- ReplaceAllocedString(&ActionLabels[i], name);
- ReplaceAllocedString(&Actions[i], command);
- nNumActions++;
- index = i;
- if (currentAction < 0) currentAction = 0;
- break;
- }
- }
- }
- }
-
- /* grow cycle gadget if necessary */
- if ((win)&&(getActionCycleWidth(win) > prevGadWidth)) UpdateWindow(win, FALSE);
- SetCurrentActionIndex(win, currentAction);
- return(index);
- }
-
- BOOL isDeviceAvailable(char * name)
- {
- struct DosList * dlist;
- BOOL ret = FALSE;
- ULONG flags = LDF_ALL | LDF_WRITE;
-
- if (dlist = LockDosList(flags))
- {
- ret = (FindDosEntry(dlist, name, flags) != NULL);
- UnLockDosList(flags);
- }
- return(ret);
- }
-
-
- int main(int argc, char **argv)
- {
- BOOL BOpenWin;
- char * hotkey, * action, * userName, * realName;
- long pri;
- char * fakeArgv[2];
- int i=0;
-
- NewList(&clientList);
- NewList(&logList);
- memset(rexxScripts, 0, sizeof(rexxScripts));
-
- /* Disable DICE's stupid CTRL-C handling--we really can't have ungraceful exits */
- signal(SIGINT, SIG_IGN);
-
- /* fix bug when called from CLI with no args */
- if ((BStartedFromWB == FALSE)&&(argc==1))
- {
- /* fake an arg */
- argc = 2;
- argv = fakeArgv;
-
- fakeArgv[0] = argv[0];
- fakeArgv[1] = "\0";
- }
- if ((BStartedFromWB == FALSE)&&(argc>=2)&&(*argv[1]=='?'))
- {
- printf("Usage: QAmiTrack SERVER/K,PORT/K/N,COMMENT/K,CX_POPUP/K,\n"
- " CX_PRIORITY/K/N,CX_POPKEY/K,ENABLE/K,\n"
- " ALLOWMULTIPLE/K,CONFIRMAPPLAUNCH/K,\n"
- " ACTION1/K,ACTION2/K,...,LEFT/K/N,TOP/K/N,\n"
- " WIDTH/K/N,HEIGHT/K/N,LOGFILE/K,LOGLEVEL/K,\n"
- " RECONNECTDELAY/K/N,RAGGEDTEXT/K,VIEWBY/K\n"
- " SORTBY/K,USERNAME/K,REALNAME/K,VISIBLETO/K\n"
- " LOGONSCRIPT/K,LOGOFFSCRIPT/K,UPDATESCRIPT/K\n"
- " CONNECTSCRIPT/K,ENDSCRIPT/K,DISCONNECTSCRIPT/K\n"
- " DISCONNECTSCRIPT/K,STARTSCRIPT/K,BEEPONLOG/K\n"
- " LOGVIEWLEVEL/K,LOGVIEWLENGTH/K/N\n");
- exit(5);
- }
-
- InitActions();
-
- atexit(Cleanup);
-
- UNLESS(IconBase = OpenLibrary("icon.library",33))
- TrackExit("Couldn't open icon.library 33+",RETURN_ERROR);
-
- UNLESS(CxBase = OpenLibrary("commodities.library", 37L))
- TrackExit("Couldn't open commodities.library v37+", RETURN_ERROR);
-
- UNLESS(WorkbenchBase = OpenLibrary("workbench.library",37))
- TrackExit("Couldn't open icon.library 37+",RETURN_ERROR);
-
- UNLESS(GraphicsBase = OpenLibrary("graphics.library", 37))
- TrackExit("Couldn't open graphics.library 37+",RETURN_ERROR);
-
- UNLESS(IntuitionBase = OpenLibrary("intuition.library", 37))
- TrackExit("Couldn't open intuition.library 37+",RETURN_ERROR);
-
- UNLESS(AMarqueeBase = OpenLibrary("amarquee.library", 46L))
- TrackExit("Couldn't open amarquee.library v46+", RETURN_ERROR);
-
- UNLESS(GadToolsBase = OpenLibrary("gadtools.library", 37))
- TrackExit("Couldn't open gadtools.library 37+",RETURN_ERROR);
-
- UNLESS(DiskFontBase = OpenLibrary("diskfont.library", 37))
- TrackExit("Couldn't open diskfont.library 37+",RETURN_ERROR);
-
- /* Parse startup arguments */
- UNLESS(ttypes = ArgArrayInit(argc, argv))
- TrackExit("Couldn't read startup arguments", RETURN_ERROR);
-
- nWinLeft = ArgInt( ttypes, "LEFT", nWinLeft);
- nWinTop = ArgInt( ttypes, "TOP", nWinTop);
- nWinWidth = ArgInt( ttypes, "WIDTH", nWinWidth);
- nWinHeight = ArgInt( ttypes, "HEIGHT", nWinHeight);
- nPort = ArgInt( ttypes, "PORT", DEFAULT_AMITRACK_PORT);
- origComment = PastSpaces(ArgString(ttypes, "COMMENT", DEFAULT_AMITRACK_COMMENT));
- pri = ArgInt( ttypes, "CX_PRIORITY", DEFAULT_AMITRACK_CXPRI);
- nReconnectDelay = ArgInt(ttypes, "RECONNECTDELAY", DEFAULT_AMITRACK_RECONNECTDELAY);
- hotkey = ArgString(ttypes, "CX_POPKEY", DEFAULT_AMITRACK_POPKEY);
- szAccessTo = ArgString(ttypes, "VISIBLETO", DEFAULT_AMITRACK_ACCESSTO);
- szLogFileName = strdup(ArgString(ttypes, "LOGFILE", DEFAULT_AMITRACK_LOGFILE)); /* strdup() it because we may need to change it! */
- nViewBy = ParseViewBy(ArgString(ttypes, "VIEWBY", DEFAULT_AMITRACK_VIEWBY));
- nSortBy = ParseSortBy(ArgString(ttypes, "SORTBY", DEFAULT_AMITRACK_SORTBY));
- nLogLevel = ParseOutputLevel(ArgString(ttypes, "LOGLEVEL", DEFAULT_AMITRACK_LOGLEVEL));
- BOpenWin = ParseBool(ArgString(ttypes, "CX_POPUP", DEFAULT_AMITRACK_CXPOPUP));
- BAllowMultiple = ParseBool(ArgString(ttypes, "ALLOWMULTIPLE", DEFAULT_AMITRACK_ALLOWMULTIPLE));
- BEnabled = ParseBool(ArgString(ttypes, "ENABLED", DEFAULT_AMITRACK_ENABLED));
- BConfirmAppLaunch = ParseBool(ArgString(ttypes, "CONFIRMAPPLAUNCH", DEFAULT_AMITRACK_CONFIRMAPP));
- BRaggedText = ParseBool(ArgString(ttypes, "RAGGEDTEXT", DEFAULT_AMITRACK_RAGGEDTEXT));
- BBeepOnLog = ParseBool(ArgString(ttypes, "BEEPONLOG", DEFAULT_AMITRACK_BEEPONLOG));
- ReplaceAllocedString(&szServerName, ArgString(ttypes, "SERVER", DEFAULT_AMITRACK_SERVER));
- nLogViewLevel = ParseLogViewLevel(ArgString(ttypes, "LOGVIEWLEVEL", DEFAULT_AMITRACK_LOGVIEWLEVEL));
- maxLogListLen = ArgInt(ttypes, "LOGVIEWLENGTH", DEFAULT_AMITRACK_LOGVIEWLENGTH);
-
- realName = ArgString(ttypes, "REALNAME", NULL);
- userName = ArgString(ttypes, "USERNAME", NULL);
-
- /* If not given, look in ENV: */
- UNLESS(userName) userName = getenv("USERNAME");
- UNLESS(userName) userName = getenv("USER");
- UNLESS(userName) userName = getenv("LOGNAME");
- UNLESS(userName) userName = "nobody";
- UNLESS(realName) realName = getenv("REALNAME");
- UNLESS(realName) realName = "anonymous";
-
- /* Record any ARexx scripts the user wants launched */
- for (i=0; i<NUM_LOG_ENUMS; i++)
- {
- UNLESS(rexxScripts[i] = strdup(ArgString(ttypes, rexxScriptNames[i], "")))
- TrackExit("Couldn't allocate Rexx script name", RETURN_ERROR);
- }
-
- for (i=0; i<20; i++)
- {
- char temp[15];
- sprintf(temp,"ACTION%i",i);
-
- if (action = (ArgString(ttypes, temp, NULL)))
- {
- char * pcTemp = strchr(action,',');
- if (pcTemp)
- {
- *pcTemp = '\0'; /* temporarily separate the string */
- ReplaceAllocedString(&ActionLabels[nNumActions],action);
- ReplaceAllocedString(&Actions[nNumActions],pcTemp+1);
- *pcTemp = ',';
- nNumActions++;
- currentAction = 0;
- }
- }
- }
-
- /* set globals */
- pcDisplayVersionString = &szVersionString[6];
-
- lLastChangeAt = time(NULL);
-
- /* Allocate our own copies of the given strings */
- UNLESS((myInfo = NewClient(""))&&
- (SetString(&myInfo->userName, userName))&&
- (SetString(&myInfo->realName, realName))&&
- (SetString(&myInfo->comment, origComment)) &&
- (SetString(&myInfo->winOpen, BOpenWin ? "Y" : "N")))
- TrackExit("Couldn't allocate local info", RETURN_ERROR);
-
- /* Force userName to be <= 8 chars */
- if (myInfo->userName->bufLen >= 9) myInfo->userName->buffer[8] = '\0';
-
- UNLESS(CX = SetupCxStuff(NULL, pri, hotkey))
- TrackExit("Couldn't setup Commodities Broker. (AmiTrack already running?)",RETURN_OK);
-
- UNLESS(TS = SetupTimer(NULL)) TrackExit("Couldn't setup timer.",RETURN_ERROR);
-
- rexxHost = SetupARexxHost(CX->name, NULL);
-
- UNLESS((BOpenWin==FALSE)||(TrackWindow = SetupTrackWindow(NULL))) TrackExit("Couldn't open GUI", RETURN_ERROR);
-
- SetMenuValues();
-
- SetTrackFlag(CODE_RECONNECT);
- SetTimer(TS, nUpdateDelay, 0);
-
- RecordEvent(LOG_START, NULL, NULL, NULL, NULL);
-
- while(1)
- {
- if (TrackFlagsSet() == FALSE) TrackWait(TrackWindow, session, rexxHost, CX, TS);
-
- if (CheckTrackFlag(CODE_TIMER))
- {
- if (TrackWindow) UpdateWindowTimes();
- connectDelayLeft -= nUpdateDelay;
- if ((session == NULL)&&(connectDelayLeft < 0))
- {
- if (nReconnectDelay >= 0) SetTrackFlag(CODE_RECONNECT);
- connectDelayLeft = nReconnectDelay*60;
- }
- SetTimer(TS, nUpdateDelay, 0);
- }
- if (CheckTrackFlag(CODE_QUIT)) break;
- if (CheckTrackFlag(CODE_WINDOW_EVENT)) HandleIDCMP(TrackWindow);
- if (CheckTrackFlag(CODE_AREXX)) ARexxDispatch(rexxHost);
- if (CheckTrackFlag(CODE_ENABLE))
- {
- BEnabled = TRUE;
- ActivateCxObj(CX->broker, 1L);
- StatMessage("AmiTrack client is now enabled.");
- if (session == NULL) SetTrackFlag(CODE_RECONNECT);
- }
- if (CheckTrackFlag(CODE_DISABLE))
- {
- ActivateCxObj(CX->broker, 0L);
- BEnabled = FALSE;
- Disconnect("AmiTrack client is now disabled.");
- }
- if (CheckTrackFlag(CODE_RECONNECT)) Reconnect();
- if (CheckTrackFlag(CODE_QMESSAGE))
- {
- struct QMessage * msg;
-
- while(msg = GetMsg(session->qMsgPort))
- {
- if ((msg->qm_Status == QERROR_SYS_MESSAGE)&&(msg->qm_Path)&&(msg->qm_Data))
- {
- char * hostNameEnd = strchr(msg->qm_Path+1, '/');
-
- if (hostNameEnd)
- {
- *hostNameEnd = '\0';
- RecordEvent(LOG_SYSMESSAGE, NULL, NULL, msg->qm_Path+1, msg->qm_Data);
- *hostNameEnd = '/';
- }
- }
- else if (msg->qm_Status == QERROR_UNPRIVILEGED)
- {
- /* Do nothing, it probably only means nobody heard our QMessageOp() */
- }
- else if (msg->qm_Status == QERROR_NO_ERROR)
- {
- if (msg->qm_ID > 0) UpdateClientList(msg);
- else if ((msg->qm_ID == 0)&&(msg->qm_Path)&&(msg->qm_Data))
- {
- if (BConnected == FALSE)
- {
- lastUpdateTime = time(NULL);
- StatMessage("Connected to server.");
- RecordEvent(LOG_CONNECT, NULL, NULL, NULL, NULL);
- BConnected = TRUE; /* Note that our connection is "live" now! */
- }
- else
- {
- /* If ID is zero, then we know QMessage is a result
- of someone doing a QMessageOp() at us! */
- UpdateClientTime(msg->qm_Path, *((ULONG *) msg->qm_Data));
- UpdateWindowTimes();
- }
- }
- }
- else /* error! */
- {
- char szMessage[250];
-
- sprintf(szMessage,"Disconnected: [%s] (line %i).", QErrorName(msg->qm_Status), msg->qm_ErrorLine);
- FreeQMessage(session, msg); /* gotta free it now as were gonna break outta the loop! */
- Disconnect(BConnected ? szMessage : NULL);
- break; /* Important to stop processing QMessages after the session has gone! */
- }
-
- /* free up message now that we're done with it! */
- FreeQMessage(session, msg);
- }
- }
- if ((CheckTrackFlag(CODE_HIDE))&&(TrackWindow))
- {
- TrackWindow = SetupTrackWindow(TrackWindow);
- SetString(&myInfo->winOpen,"N");
- SendState(STATE_WINOPEN);
- }
- if (CheckTrackFlag(CODE_SHOW))
- {
- if (TrackWindow) ActivateWindow(TrackWindow->win);
- else
- {
- TrackWindow = SetupTrackWindow(NULL);
- StatMessage(NULL); /* Show last message */
- SetString(&myInfo->winOpen,"Y");
- SendState(STATE_WINOPEN);
- }
- }
- SetMenuValues();
- }
-
- /* Cleanup() called here! */
- }
-