Пример #1
0
int autoconnect(fd_set *master, int *fdmax, servlist *serv) // XXX broken in the face of asynch nl [I have forgotten what was meant by this; I'm not aware of anything broken about this function]
{
	servlist *curr=serv;
	if(!curr) return(0);
	#if ASYNCH_NL
	char cstr[36+strlen(serv->name)+strlen(serv->portno)];
	sprintf(cstr, "Connecting to %s on port %s...", serv->name, serv->portno);
	nl_list *list=irc_connect(serv->name, serv->portno);
	if(!list) return(autoconnect(master, fdmax, serv->next));
	add_to_buffer(0, STA, QUIET, 0, false, cstr, "auto: ");
	list->reconn_b=0;
	list->autoent=serv;
	#else /* ASYNCH_NL */
	char cstr[36+strlen(serv->name)+strlen(serv->portno)];
	sprintf(cstr, "Connecting to %s on port %s...", serv->name, serv->portno);
	add_to_buffer(0, STA, QUIET, 0, false, cstr, "auto: ");
	int serverhandle=irc_connect(serv->name, serv->portno, master, fdmax);
	if(serverhandle)
	{
		bufs=(buffer *)realloc(bufs, ++nbufs*sizeof(buffer));
		cbuf=nbufs-1;
		init_buffer(cbuf, SERVER, serv->name, buflines);
		bufs[cbuf].handle=serverhandle;
		bufs[cbuf].nick=strdup(serv->nick);
		bufs[cbuf].autoent=serv;
		if(serv) bufs[cbuf].ilist=n_dup(serv->igns);
		bufs[cbuf].server=cbuf;
		bufs[cbuf].conninpr=true;
		add_to_buffer(cbuf, STA, QUIET, 0, false, cstr, "auto: ");
		redraw_buffer();
	}
	#endif /* ASYNCH_NL */
	autoconnect(master, fdmax, serv->next);
	return(1);
}
Пример #2
0
int init_buffer(int buf, btype type, const char *bname, int nlines)
{
	bufs[buf].type=type;
	bufs[buf].bname=strdup(bname);
	if(type==SERVER)
		bufs[buf].serverloc=strdup(bname);
	else
		bufs[buf].serverloc=NULL;
	bufs[buf].realsname=NULL;
	bufs[buf].nlist=NULL;
	bufs[buf].us=NULL;
	bufs[buf].ilist=NULL;
	bufs[buf].handle=0;
	bufs[buf].server=0;
	bufs[buf].nick=NULL;
	bufs[buf].topic=NULL;
	bufs[buf].logf=NULL;
	bufs[buf].nlines=nlines;
	bufs[buf].ptr=0;
	bufs[buf].scroll=0;
	bufs[buf].ascroll=0;
	bufs[buf].lm=malloc(nlines*sizeof(mtype));
	bufs[buf].lq=malloc(nlines*sizeof(prio));
	bufs[buf].lp=malloc(nlines);
	bufs[buf].ls=malloc(nlines*sizeof(bool));
	bufs[buf].lt=malloc(nlines*sizeof(char *));
	int i;
	for(i=0;i<bufs[buf].nlines;i++)
	{
		bufs[buf].lt[i]=NULL;
	}
	bufs[buf].ltag=malloc(nlines*sizeof(char *));
	for(i=0;i<bufs[buf].nlines;i++)
	{
		bufs[buf].ltag[i]=NULL;
	}
	bufs[buf].lpl=malloc(nlines*sizeof(int));
	bufs[buf].lpc=malloc(nlines*sizeof(colour));
	bufs[buf].lpt=malloc(nlines*sizeof(char **));
	for(i=0;i<nlines;i++)
	{
		bufs[buf].lpl[i]=0;
		bufs[buf].lpc[i]=(colour){.fore=7, .back=0, .hi=false, .ul=false};
		bufs[buf].lpt[i]=NULL;
	}
	bufs[buf].dirty=false;
	bufs[buf].ts=malloc(nlines*sizeof(time_t));
	bufs[buf].filled=false;
	bufs[buf].alert=false;
	bufs[buf].hi_alert=0;
	bufs[buf].ping=0;
	bufs[buf].last=time(NULL);
	bufs[buf].namreply=false;
	bufs[buf].live=false;
	bufs[buf].conninpr=false;
	initibuf(&bufs[buf].input);
	bufs[buf].casemapping=RFC1459;
	if(type==SERVER)
	{
		bufs[buf].npfx=2;
		bufs[buf].prefixes=malloc(2*sizeof(prefix));
		bufs[buf].prefixes[0]=(prefix){.letter='o', .pfx='@'};
		bufs[buf].prefixes[1]=(prefix){.letter='v', .pfx='+'};
	}
	else
	{
		bufs[buf].npfx=0;
		bufs[buf].prefixes=NULL;
	}
	bufs[buf].autoent=NULL;
	bufs[buf].conf=conf;
	bufs[buf].key=NULL;
	bufs[buf].lastkey=NULL;
	return(0);
}

int free_buffer(int buf)
{
	if(bufs[buf].live)
	{
		add_to_buffer(buf, ERR, NORMAL, 0, false, "Buffer is still live!", "free_buffer:");
		return(1);
	}
	else
	{
		free(bufs[buf].bname);
		free(bufs[buf].serverloc);
		free(bufs[buf].realsname);
		n_free(bufs[buf].nlist);
		bufs[buf].nlist=NULL;
		n_free(bufs[buf].ilist);
		bufs[buf].ilist=NULL;
		free(bufs[buf].nick);
		free(bufs[buf].topic);
		if(bufs[buf].logf)
			fclose(bufs[buf].logf);
		free(bufs[buf].lm);
		free(bufs[buf].lq);
		free(bufs[buf].lp);
		free(bufs[buf].ls);
		int l;
		if(bufs[buf].lt)
		{
			for(l=0;l<bufs[buf].nlines;l++)
				free(bufs[buf].lt[l]);
			free(bufs[buf].lt);
		}
		if(bufs[buf].ltag)
		{
			for(l=0;l<bufs[buf].nlines;l++)
				free(bufs[buf].ltag[l]);
			free(bufs[buf].ltag);
		}
		if(bufs[buf].lpt)
		{
			for(l=0;l<bufs[buf].nlines;l++)
			{
				if(bufs[buf].lpt[l])
				{
					if(bufs[buf].lpl)
					{
						int p;
						for(p=0;p<bufs[buf].lpl[l];p++)
						{
							free(bufs[buf].lpt[l][p]);
						}
					}
					free(bufs[buf].lpt[l]);
				}
			}
			free(bufs[buf].lpt);
		}
		free(bufs[buf].lpl);
		free(bufs[buf].lpc);
		free(bufs[buf].ts);
		freeibuf(&bufs[buf].input);
		free(bufs[buf].prefixes);
		free(bufs[buf].key);
		free(bufs[buf].lastkey);
		if(cbuf>=buf)
			cbuf--;
		nbufs--;
		int b;
		for(b=buf;b<nbufs;b++)
		{
			bufs[b]=bufs[b+1];
		}
		for(b=0;b<nbufs;b++)
		{
			if(bufs[b].server==buf)
			{
				bufs[b].server=0; // orphaned; should not happen
				bufs[b].live=false;
				bufs[b].handle=0; // just in case
			}
			else if(bufs[b].server>buf)
			{
				bufs[b].server--;
			}
		}
		if(nbufs) redraw_buffer();
		return(0);
	}
}

int add_to_buffer(int buf, mtype lm, prio lq, char lp, bool ls, const char *lt, const char *ltag)
{
	if(buf>=nbufs)
	{
		if(bufs&&buf)
		{
			add_to_buffer(0, ERR, NORMAL, 0, false, "Line was written to bad buffer!  Contents below.", "add_to_buffer(): ");
			add_to_buffer(0, lm, NORMAL, lp, ls, lt, ltag);
		}
		return(1);
	}
	if(!debug&&(lq==DEBUG))
	{
		if(!d_buf.nlines)
		{
			init_ring(&d_buf);
			d_buf.loop=true;
		}
		return(add_to_ring(&d_buf, lm, lt, ltag));
	}
	int optr=bufs[buf].ptr;
	bool scrollisptr=(bufs[buf].scroll==bufs[buf].ptr)&&(bufs[buf].ascroll==0);
	bufs[buf].lm[bufs[buf].ptr]=lm;
	bufs[buf].lq[bufs[buf].ptr]=lq;
	bufs[buf].lp[bufs[buf].ptr]=lp;
	bufs[buf].ls[bufs[buf].ptr]=ls;
	free(bufs[buf].lt[bufs[buf].ptr]);
	bufs[buf].lt[bufs[buf].ptr]=strdup(lt);
	free(bufs[buf].ltag[bufs[buf].ptr]);
	bufs[buf].ltag[bufs[buf].ptr]=strdup(ltag);
	time_t ts=bufs[buf].ts[bufs[buf].ptr]=time(NULL);
	bufs[buf].ptr=(bufs[buf].ptr+1)%bufs[buf].nlines;
	if(scrollisptr)
	{
		bufs[buf].scroll=bufs[buf].ptr;
		bufs[buf].ascroll=0;
	}
	if(bufs[buf].ptr==0)
		bufs[buf].filled=true;
	render_line(buf, optr);
	if(buf==cbuf)
	{
		int e=redraw_buffer();
		if(e) return(e);
	}
	else
	{
		if(!(
			(bufs[buf].conf&&((lm==JOIN)||(lm==PART)||(lm==NICK)||(lm==MODE)||(lm==QUIT)))
			||
				(quiet&&(lq==QUIET))
			||
				(!debug&&(lq==DEBUG))
			))
		bufs[buf].alert=true;
	}
	if(bufs[buf].logf)
	{
		int e=log_add(bufs[buf].logf, bufs[buf].logt, lm, lq, lp, ls, lt, ltag, ts);
		if(e) return(e);
	}
	return(0);
}

int redraw_buffer(void)
{
	if(bufs[cbuf].dirty)
	{
		int e=render_buffer(cbuf);
		if(e) return(e);
		if(bufs[cbuf].dirty) return(1);
	}
	int uline=bufs[cbuf].scroll;
	int pline=bufs[cbuf].ascroll;
	while(pline<0)
	{
		uline--;
		if((bufs[cbuf].filled)&&(uline==bufs[cbuf].ptr))
		{
			uline++;
			pline=0;
			break;
		}
		if(uline<0)
		{
			if(bufs[cbuf].filled)
				uline+=bufs[cbuf].nlines;
			else
			{
				uline=0;
				pline=0;
				break;
			}
		}
		pline+=bufs[cbuf].lpl[uline];
	}
	if(uline==bufs[cbuf].ptr)
	{
		pline=0;
	}
	while(pline>=bufs[cbuf].lpl[uline])
	{
		pline-=bufs[cbuf].lpl[uline];
		if(bufs[cbuf].filled)
		{
			if(uline==bufs[cbuf].ptr)
			{
				pline=0;
				break;
			}
			uline=(uline+1)%bufs[cbuf].nlines;
		}
		else
		{
			if(uline>=bufs[cbuf].ptr)
			{
				uline=bufs[cbuf].ptr;
				pline=0;
				break;
			}
			uline++;
		}
	}
	bufs[cbuf].scroll=uline;
	bufs[cbuf].ascroll=pline;
	int row=height-2;
	//setcolour(bufs[cbuf].lpc[uline]);
	while(row>(tsb?1:0))
	{
		bool breakit=false;
		pline--;
		while(pline<0)
		{
			uline--;
			if(uline<0)
			{
				if(bufs[cbuf].filled)
					uline+=bufs[cbuf].nlines;
				else
				{
					breakit=true;
					pline=0;
					break;
				}
			}
			if(uline==bufs[cbuf].ptr)
			{
				breakit=true;
				break;
			}
			pline+=bufs[cbuf].lpl[uline];
		}
		if(breakit) break;
		locate(row, 0);
		fputs(bufs[cbuf].lpt[uline][pline], stdout);
		if(!full_width_colour) resetcol();
		clr();
		row--;
	}
	resetcol();
	while(row>(tsb?1:0))
	{
		locate(row--, 0);
		clr();
	}
	switch(bufs[cbuf].type)
	{
		case STATUS:
			settitle("quIRC - status");
		break;
		case SERVER: // have to scope it for the cstr 'variably modified type'
			{
				char cstr[16+strlen(bufs[cbuf].bname)];
				sprintf(cstr, "quIRC - %s", bufs[cbuf].bname);
				settitle(cstr);
			}
		break;
		case CHANNEL: // have to scope it for the cstr 'variably modified type'
			{
				char cstr[16+strlen(bufs[cbuf].bname)+strlen(SERVER(cbuf).bname)];
				sprintf(cstr, "quIRC - %s on %s", bufs[cbuf].bname, SERVER(cbuf).bname);
				settitle(cstr);
			}
		break;
		case PRIVATE: // have to scope it for the cstr 'variably modified type'
			{
				char cstr[16+strlen(bufs[cbuf].bname)+strlen(SERVER(cbuf).bname)];
				sprintf(cstr, "quIRC - <%s> on %s", bufs[cbuf].bname, SERVER(cbuf).bname);
				settitle(cstr);
			}
		break;
		default:
			settitle("quIRC");
		break;
	}
	if(tsb)
		titlebar();
	bufs[cbuf].alert=false;
	return(0);
}

int mark_buffer_dirty(int buf)
{
	bufs[buf].dirty=true;
	return(0);
}