-
-void Cmd_join(char *ArgString)
-{
- int pos=0;
- char *channel_name = GetValue(ArgString, &pos);
-
- if( gpCurrentWindow->Server )
- {
- gpCurrentWindow = Window_Create(gpCurrentWindow->Server, channel_name);
- Redraw_Screen();
- writef(gpCurrentWindow->Server->FD, "JOIN :%s\n", channel_name);
- }
-}
-
-void Cmd_quit(char *ArgString)
-{
- const char *quit_message = ArgString;
- if( quit_message == NULL || quit_message[0] == '\0' )
- quit_message = "/quit - Acess2 IRC Client";
-
- for( tServer *srv = gpServers; srv; srv = srv->Next )
- {
- writef(srv->FD, "QUIT :%s\n", quit_message);
- }
-
- exit(0);
-}
-
-void Cmd_window(char *ArgString)
-{
- int pos = 0;
- char *window_id = GetValue(ArgString, &pos);
- int window_num = atoi(window_id);
-
- if( window_num > 0 )
- {
- tWindow *win;
- window_num --; // Move to base 0
- // Get `window_num`th window
- for( win = gpWindows; win && window_num--; win = win->Next );
- if( win ) {
- gpCurrentWindow = win;
- Redraw_Screen();
- }
- // Otherwise, silently ignore
- }
- else
- {
- window_num = 1;
- for( tWindow *win = gpWindows; win; win = win->Next, window_num ++ )
- {
- if( win->Name[0] ) {
- Message_AppendF(NULL, MSG_TYPE_SERVER, "client", "",
- "%i: %s/%s", window_num, win->Server->Name, win->Name);
- }
- else {
- Message_AppendF(NULL, MSG_TYPE_SERVER, "client", "",
- "%i: (status)", window_num);
- }
- }
- }
-}
-
-const struct {
- const char *Name;
- void (*Fcn)(char *ArgString);
-} caCommands[] = {
- {"join", Cmd_join},
- {"quit", Cmd_quit},
- {"window", Cmd_window},
- {"win", Cmd_window},
- {"w", Cmd_window},
-};
-const int ciNumCommands = sizeof(caCommands)/sizeof(caCommands[0]);
-
-/**
- * \brief Handle a line from the prompt
- */
-int ParseUserCommand(char *String)
-{
- if( String[0] == '/' )
- {
- char *command;
- int pos = 0;
-
- command = GetValue(String, &pos)+1;
-
- // TODO: Prefix matches
- int cmdIdx = -1;
- for( int i = 0; i < ciNumCommands; i ++ )
- {
- if( strcmp(command, caCommands[i].Name) == 0 ) {
- cmdIdx = i;
- break;
- }
- }
- if( cmdIdx != -1 ) {
- caCommands[cmdIdx].Fcn(String+pos);
- }
- else
- {
- Message_AppendF(NULL, MSG_TYPE_SERVER, "client", "", "Unknown command %s", command);
- }
- }
- else
- {
- // Message
- // - Only send if server is valid and window name is non-empty
- if( gpCurrentWindow->Server && gpCurrentWindow->Name[0] )
- {
- Message_Append(gpCurrentWindow->Server, MSG_TYPE_STANDARD,
- gsNickname, gpCurrentWindow->Name, String);
- writef(gpCurrentWindow->Server->FD,
- "PRIVMSG %s :%s\n", gpCurrentWindow->Name,
- String
- );
- }
- }
-
- return 0;
-}
-
-/**
- * \brief Connect to a server
- */
-tServer *Server_Connect(const char *Name, const char *AddressString, short PortNumber)
-{
- tServer *ret;
-
- ret = calloc(1, sizeof(tServer) + strlen(Name) + 1);
-
- strcpy(ret->Name, Name);
-
- // Connect to the remove server
- ret->FD = OpenTCP( AddressString, PortNumber );
- if( ret->FD == -1 ) {
- fprintf(stderr, "%s: Unable to create socket\n", Name);
- return NULL;
- }
-
- // Append to open list
- ret->Next = gpServers;
- gpServers = ret;
-
- // Read some initial data
- Message_Append(NULL, MSG_TYPE_SERVER, Name, "", "Connection opened");
- ProcessIncoming(ret);
-
- // Identify
- writef(ret->FD, "USER %s %s %s : %s\n", gsUsername, gsHostname, AddressString, gsRealName);
- writef(ret->FD, "NICK %s\n", gsNickname);
- Message_Append(NULL, MSG_TYPE_SERVER, Name, "", "Identified");
- //printf("%s: Identified\n", Name);
-
- return ret;
-}
-
-tMessage *Message_AppendF(tServer *Server, int Type, const char *Source, const char *Dest, const char *Message, ...)
-{
- va_list args;
- int len;
- va_start(args, Message);
- len = vsnprintf(NULL, 0, Message, args);
- va_end(args);
-
- char buf[len+1];
- va_start(args, Message);
- vsnprintf(buf, len+1, Message, args);
- va_end(args);
-
- return Message_Append(Server, Type, Source, Dest, buf);
-}
-
-tMessage *Message_Append(tServer *Server, int Type, const char *Source, const char *Dest, const char *Message)
-{
- tWindow *win = NULL;
- int msgLen = strlen(Message);
-
- // Server==NULL indicates an internal message
- if( Server == NULL || Source[0] == '\0' )
- {
- win = &gWindow_Status;
- }
- // Determine if it's a channel or PM
- else if( Dest[0] == '#' || Dest[0] == '&' ) // TODO: Better determining here
- {
- for(win = gpWindows; win; win = win->Next)
- {
- if( win->Server == Server && strcmp(win->Name, Dest) == 0 )
- {
- break;
- }
- }
- if( !win ) {
- //win = Window_Create(Server, Dest);
- win = &gWindow_Status; // Stick it in the status window, just in case
- }
- }
- #if 0
- else if( strcmp(Dest, Server->Nick) != 0 )
- {
- // Umm... message for someone who isn't us?
- win = &gWindow_Status; // Stick it in the status window, just in case
- }
- #endif
- // Server message?
- else if( strchr(Source, '.') ) // TODO: And again, less hack please
- {
- #if 1
- for(win = gpWindows; win; win = win->Next)
- {
- if( win->Server == Server && strcmp(win->Name, Source) == 0 )
- {
- break;
- }
- }
- #endif
- if( !win ) {
- win = &gWindow_Status;
- }
-
- // Set source to the server name (instead of the hostname)
- Source = Server->Name;
- }
- // Private message
- else
- {
- for(win = gpWindows; win; win = win->Next)
- {
- if( win->Server == Server && strcmp(win->Name, Source) == 0 )
- {
- break;
- }
- }
- if( !win ) {
- win = Window_Create(Server, Dest);
- }
- }
-
- // Create message cache
- _SysDebug("Win (%s) msg: <%s> %s", win->Name, Source, Message);
- tMessage *ret;
- ret = malloc( sizeof(tMessage) + msgLen + 1 + strlen(Source) + 1 );
- ret->Source = ret->Data + msgLen + 1;
- strcpy(ret->Source, Source);
- strcpy(ret->Data, Message);
- ret->Type = Type;
- ret->Server = Server;
-
- // Append to window message list
- ret->Next = win->Messages;
- win->Messages = ret;
-
- // Print now if current window
- if( win == gpCurrentWindow )
- {
- printf("\33[s");
- printf("\33[T"); // Scroll down 1 (free space below)
- SetCursorPos(giTerminal_Height-2, 0);
- int prefixlen = strlen(Source) + 3;
- int avail = giTerminal_Width - prefixlen;
- int msglen = strlen(Message);
- printf("[%s] %.*s", Source, avail, Message);
- while( msglen > avail ) {
- msglen -= avail;
- Message += avail;
- printf("\33[T");
- SetCursorPos(giTerminal_Height-2, prefixlen);
- printf("%.*s", avail, Message);
- }
- printf("\x1b[u");
- }
-
- return ret;
-}
-
-tWindow *Window_Create(tServer *Server, const char *Name)
-{
- tWindow *ret, *prev = NULL;
- int num = 1;
-
- // Get the end of the list
- // TODO: Cache this instead
- for( ret = gpCurrentWindow; ret; prev = ret, ret = ret->Next )
- num ++;
-
- ret = malloc(sizeof(tWindow) + strlen(Name) + 1);
- ret->Messages = NULL;
- ret->Server = Server;
- ret->ActivityLevel = 1;
- strcpy(ret->Name, Name);
-
- if( prev ) {
- ret->Next = prev->Next;
- prev->Next = ret;
- }
- else { // Shouldn't happen really
- ret->Next = gpWindows;
- gpWindows = ret;
- }
-
-// printf("Win %i %s:%s created\n", num, Server->Name, Name);
-
- return ret;
-}
-