Пример #1
0
/** 
 * \brief Saves the InfoServ database to disk
 */
void saveInfoData(void)
{
	SomeNews *news = NULL;
	int index = 0;

	db.is = fopen(IS_DB, "w");

	if (db.is == NULL) {
		sSend(":%s GOPER :ERROR: Unable to save Info Article database fopen failed: %s", myname, strerror(errno));
		logDump(corelog, "Unable to save Info Article database: fopen: %s", strerror(errno));
		return;
	}

	/*! \bug Huh? Why check for NULL -twice- ? */
	if (is_listhead != NULL) {	/* In case list is empty, thanks to Echostar for pointing this cack-handed error out...  */
		for (news = is_listhead, index = 0; news;
			 news = news->next, index++)
		{
			fprintf(db.is, "article %i %s %li %s\n", news->importance,
					news->from, news->timestamp, news->header);
			dbWriteString(db.is, news->content);
		}
	}

	fprintf(db.is, "done\n");

	fclose(db.is);

	sSend(":%s PRIVMSG " LOGCHAN " :Completed save(%i articles)", InfoServ,
		  index);
}
Пример #2
0
/*!
 * \fn void handler(int signal)
 * \brief Signal handler
 * \param signal A signal number (such as SIGTERM)
 * This is the function used by services to handle signals.
 */
void handler(int sig)
{
    switch (sig) {
    case SIGTERM:
        sSend("WALLOPS "
              ":Received some signal thats telling me to shutdown");
        timed_akill_queue(NULL);
        sshutdown(0);
        break;
    case SIGSEGV:
        timed_akill_queue(NULL);
        logDump(corelog, "Core dumped ---\n\"%s\"", coreBuffer);
        sSend("WALLOPS :Segmentation Violation, shutdown NOW");
        sSend("GOPER :Buffer is -> %s", coreBuffer);
        dlogDump(corelog);
        sshutdown(1);
        break;

    case SIGPIPE:
        timed_akill_queue(NULL);
        signal(SIGPIPE, SIG_IGN);  /*! \bug XXXMLG probably not QUITE right */
        /*		sshutdown(0);*/
        break;

    default:
        sSend("GNOTICE :Recieved unidentified signal %i", sig);
        return;
    }
}
Пример #3
0
/**
 *  Add a new user, be that ChanServ or a nick in holding.
 * in the 'mode' variable you can specify +iogsw or any other ircd
 * compatible modes.
 * \par Used at services startup
 */
void
addUser(char *nick, char *user, char *host, char *name, char *mode)
{
	if (!nick || !*nick) {
		return;
	}
	sSend("NICK %s 1 0 %s %s %s :%s", nick, user, host, myname, name);
	sSend(":%s MODE %s :%s", nick, nick, mode);
}
Пример #4
0
/** 
 * \brief Saves the Clone rule database to disk
 */
void saveTriggerData(void)
{
	int totrules = 0;
	CloneRule *rule;
	extern CloneRule *first_crule;

	db.trigger = fopen(TRG_DB, "w");
	if (!db.trigger) {
		logDump(corelog,
				"Unable to open trigger database for read access: %s",
				strerror(errno));
		sSend
			(":%s GLOBOPS :Unable to open trigger database for read access: %s",
			 NickServ, strerror(errno));
		return;
	}
	for (rule = first_crule; rule; rule = rule->next, ++totrules) {
		if (fprintf
			(db.trigger, "Trigger %s %d %d %ld\n", rule->mask,
			 rule->trigger, rule->utrigger, rule->flags) < 0) {
			logDump(corelog,
					"Error in writing rule to trigger database: %s",
					strerror(errno));
			break;
		}
		if (rule->kill_msg) {
			if ((fprintf(db.trigger, "Killmsg %s\n", rule->kill_msg)) < 0) {
				logDump(corelog,
						"Error in writing trigger rule (killmsg) to trigger database: %s",
						strerror(errno));
				break;
			}
		}
		if (rule->warn_msg) {
			if ((fprintf(db.trigger, "Warnmsg %s\n", rule->warn_msg)) < 0) {
				logDump(corelog,
						"Error in writing trigger rule (warnlmsg) to trigger database: %s",
						strerror(errno));
				break;
			}
		}
	}
	fprintf(db.trigger, "done\n");

	if (fclose(db.trigger) < 0) {
		logDump(corelog, "Error closing trigger database: %s",
				strerror(errno));
		return;
	}
	sSend(":%s PRIVMSG " LOGCHAN " :Completed trigger save (%u rules)",
		  OperServ, totrules);
}
Пример #5
0
/**
 * Respond to an /INFO message
 * \param nick Pointer to online user item
 */
void
sendInfoReply(UserList * nick)
{
	char *from = nick->nick;
	extern char *services_info[];
	int i = 0;

	sSend(":%s 373 %s :Server INFO", myname, from);
	for (i = 0; services_info[i]; i++)
		sSend(":%s 371 %s :%s", myname, from, services_info[i]);
	sSend(":%s 374 %s :End of /INFO list.", myname, from);
	return;
}
Пример #6
0
/** 
 * \brief Saves the URLS of channels to urls.txt
 */
void saveChanUrls(RegChanList * first)
{
return;
	RegChanList *cl = first;
	const char *tmpFounderNick;
	FILE *fpOut;
	char cstr[258];

	fpOut = fopen(CS_DIR "urls.txt.new", "w");
	if (!fpOut)
		return;
	while (cl) {
		if (!cl->name || !*cl->name || (cl->restrictlevel > 0)) {
			cl = cl->next;
			continue;
		}
		if (cl->mlock & (PM_S | PM_P | PM_I | PM_K)) {
			cl = cl->next;
			continue;
		}

		tmpFounderNick = cl->founderId.getNick();

		if (tmpFounderNick == NULL)
			tmpFounderNick = "-";

		sprintf(cstr, ":%.255s",
				md5_printable(md5_password((u_char *)cl->password)));
		fprintf(fpOut, "C %s %s %ld %ld %s\n", cl->name,
				tmpFounderNick, cl->mlock, cl->flags,
				md5_printable(md5_password((u_char *)cstr)));
		memset(cstr, 0, 255);
		if (cl->topic)
			fprintf(fpOut, "topic %s %s %lu :%s\n", cl->name,
					*cl->tsetby ? cl->tsetby : "-", cl->ttimestamp,
					cl->topic);
		if (cl->url)
			fprintf(fpOut, "url %s :%s\n", cl->name, cl->url);
		fflush(fpOut);
		cl = cl->next;
	}
	if (fclose(fpOut) < 0) {
		sSend("GLOBOPS :Fatal error in writing out urls.txt.new.");
		return;
	}
	if (rename("chanserv/urls.txt.new", "chanserv/urls.txt") < 0) {
		sSend("GLOBOPS :Error renaming urls.txt.new.");
		return;
	}
}
Пример #7
0
int send_from_fifo(int fd)
{
	int len;

	if( !session_isValid(fd) )
		return -1;

	if( session[fd]->wdata_size == 0 )
		return 0; // nothing to send

	len = sSend(fd, (const char *) session[fd]->wdata, (int)session[fd]->wdata_size, 0);

	if( len == SOCKET_ERROR )
	{//An exception has occured
		if( sErrno != S_EWOULDBLOCK ) {
			//ShowDebug("send_from_fifo: error %d, ending connection #%d\n", sErrno, fd);
			session[fd]->wdata_size = 0; //Clear the send queue as we can't send anymore. [Skotlex]
			set_eof(fd);
		}
		return 0;
	}

	if( len > 0 )
	{
		// some data could not be transferred?
		// shift unsent data to the beginning of the queue
		if( (size_t)len < session[fd]->wdata_size )
			memmove(session[fd]->wdata, session[fd]->wdata + len, session[fd]->wdata_size - len);

		session[fd]->wdata_size -= len;
	}

	return 0;
}
Пример #8
0
/**
 * @brief Make a fake mass client
 */
char *
make_clone()
{
	static char rand_nick[NICKLEN + 1];
	char rand_user[USERLEN + 1];
	char host[HOSTLEN + 1], blip1[6], blip2[5];
	char rand_ircname[50];
	int fails = 0;

	(void)ranstring(rand_nick, NICKLEN - 1, 0);
	(void)ranstring(rand_user, USERLEN - 1, 2);
	(void)ranstring(rand_ircname, sizeof(rand_ircname) - 1, 1);
	(void)ranstring(blip1, sizeof(blip1) - 1, 0);
	(void)ranstring(blip2, sizeof(blip2) - 1, 1);

	snprintf(host, sizeof(host), "services-%lx.%s-sorcery-massdetect.net",
		 (time(0)/30)%1000, blip1);


	if (getNickData(rand_nick) || getRegNickData(rand_nick)) {
		while ((getNickData(rand_nick) || getRegNickData(rand_nick)) && fails < 50) {
			(void)ranstring(rand_nick, NICKLEN - 1, 0);
			if (fails++ > 20)
				return NULL;
			else if (fails > 1 && fails < 3)
				sSend("GLOBOPS :[***] make_clone(MassServ): nick %s already exists",
						 rand_nick);
		}
	}

	addUser(rand_nick, rand_user, host, rand_ircname, "+m");
	return rand_nick;
}
Пример #9
0
/*!
 * \fn void sshutdown(int type)
 * \brief Shuts down services
 * \param type specifies type of shutdown (fatal error, normal exit, etc)
 *
 * \bug XXXMLG This needs to be done better...  I suggest #defines for the
 * various things we want this function to do (save data, send message,
 * etc) and then use something like:
 *      sshutdown(SHUTDOWN_SAVE | SHUTDOWN_MSG, "This is the message");
 */
void sshutdown(int type)
{
    if (type != (-1) && type != 2) {
        writeServicesTotals();
        saveakills();
        saveNickData();
        syncChanData(1);
        saveMemoData();
        saveInfoData();
    }

    timed_akill_queue(NULL);
    unlink("services.pid");

    if (1 /*type == 0 || type == -1 || type > 2 */ ) {
#ifdef USE_SQL
        if (dbConn != NULL)
            PQfinish(dbConn);
        dbConn = NULL;
#endif
    }

    if (type == 1) {
        sSend("SQUIT %s :Services %s fall down go BOOM!", hostname,
              VERSION_NUM);
        close(server);
        abort(); 				/* dump a core file */
    }
    else if (type == 2) {				/* No connection to server established */
        fprintf(stderr,
                "Error connecting to server, check above message\n");
        exit(-1);
    }
    else if (type == 0) {
        sSend("SQUIT %s :Services %s shutdown", hostname, VERSION_NUM);
        if (server != -1) {
            close(server);
        }
        exit(66);
    }
    else {
        sSend("SQUIT %s :Services %s shutdown", hostname, VERSION_NUM);
        close(server);
        exit(1);
    }
}
Пример #10
0
/**
 * @param source Sender nickname
 * @param buf Message text
 * @param which Value indicating which client received the message
 * @brief handle an incoming message to a MassServ fake client
 */
void detect_mass(UserList *nl_from, char *buf, int which)
{
	aMassAd *booya;
	aMassAd *f1, *f2, *f1o, *f2o;

	expire_ads();

	if (nl_from != 0) {
		f1o = f1 = find_ad(nl_from, 0);
		f2o = f2 = find_ad(nl_from, 1);
	} 
	else
		return;

	if (nl_from && ((!f1 && which == 0) || (!f2 && which == 1))) {
		booya = (aMassAd *) oalloc(sizeof(aMassAd));
		booya->sender = nl_from;
		booya->utc = time(NULL);
		booya->rcvd_by = which;
		insert_ad(booya);
		if (!booya->sender)
			logDump(corelog,
					"[***] bug: booya->sender is NULL in detect_mass()");
	}

	if (f1 == NULL)
		f1 = find_ad(nl_from, 0);
	if (f2 == NULL)
		f2 = find_ad(nl_from, 1);

	if (f1 != NULL && f2 != NULL) {
		sSend(":%s GLOBOPS :\2Mass Ad:\2 (%s) %s",
			  MassServ, nl_from->nick, buf);
		flush_ad(nl_from);
		// sSend(":%s SVSKILL %s :killed ([services] (Mass msg'ing))", source);
	} else if (!f1o && !f2o)
		sSend(":%s GLOBOPS :(Debug) \2Possible Mass Ad:\2 (%s) %s", MassServ,
			  nl_from->nick, buf);
	return;
}
Пример #11
0
/**
 * @brief Maintain the advert detection bots' presence and expire old
 *        advert information periodically
 */
void adCloneMaintenance()
{
	char *y;
	int k;

	if (massAdClones[0] == 0 && massAdClones[1] == 0) {
		if ((y = make_clone())) {
			massAdClones[0] = strdup(y);
			if ((y = make_clone()))
				massAdClones[1] = strdup(y);
		}
		massAdClones[2] = massAdClones[3] = massAdClones[4] = NULL;
	}
	else {
		if (massAdClones[0])
		{
			sSend(":%s QUIT :%s", massAdClones[0], massAdClones[0]);
			massAdClones[2] = massAdClones[0];
			if ((y = make_clone()))
				massAdClones[0] = strdup(y);
		}

		if (massAdClones[1])
		{
			sSend(":%s QUIT :%s", massAdClones[1], massAdClones[1]);
			massAdClones[3] = massAdClones[1];
			if ((y = make_clone()))
				massAdClones[1] = strdup(y);
		}

		for(k = 2; k < 4; k++)
		{
			if (massAdClones[k]) {
				FREE(massAdClones[k]);
				massAdClones[k] = 0;
			}
		}
	}
}
Пример #12
0
void checkTusers(char *)
{
#ifdef PLUSLCHAN
    static u_int last_mostusers = 0;

    if (last_mostusers < mostusers) {
        sSend(":%s MODE %s +l %lu", OperServ, PLUSLCHAN, mostusers + 5);
        last_mostusers = mostusers;
    }

    timer(60, checkTusers, NULL);
#endif
}
Пример #13
0
int send_from_fifo(int fd)
{
	ssize_t len;

	if( !sockt->session_isValid(fd) )
		return -1;

	if( session[fd]->wdata_size == 0 )
		return 0; // nothing to send

	len = sSend(fd, (const char *) session[fd]->wdata, (int)session[fd]->wdata_size, MSG_NOSIGNAL);

	if( len == SOCKET_ERROR )
	{//An exception has occured
		if( sErrno != S_EWOULDBLOCK ) {
			//ShowDebug("send_from_fifo: %s, ending connection #%d\n", error_msg(), fd);
#ifdef SHOW_SERVER_STATS
			socket_data_qo -= session[fd]->wdata_size;
#endif
			session[fd]->wdata_size = 0; //Clear the send queue as we can't send anymore. [Skotlex]
			set_eof(fd);
		}
		return 0;
	}

	if( len > 0 )
	{
		// some data could not be transferred?
		// shift unsent data to the beginning of the queue
		if( (size_t)len < session[fd]->wdata_size )
			memmove(session[fd]->wdata, session[fd]->wdata + len, session[fd]->wdata_size - len);

		session[fd]->wdata_size -= len;
#ifdef SHOW_SERVER_STATS
		socket_data_o += len;
		socket_data_qo -= len;
		if (!session[fd]->flag.server)
		{
			socket_data_co += len;
		}
#endif
	}

	return 0;
}
Пример #14
0
void readRegData(void) {
        char tmp2[10 + HOSTLEN], tmp[10];
        int lineread = 1, i;
        db.nsreg = fopen("nickserv/nickregs.db", "r");
        if(!db.nsreg)
          return;
        while(sfgets(tmp, 10, db.nsreg)) {
                if(tmp[0] != '-') {
                        sSend("GOPER :!ERROR! NickServ databases are corrupted (line %i)", lineread);
                        sshutdown(1);
                }
                sfgets(tmp2, 10 + HOSTLEN, db.nsreg);
                addNReg(tmp2);
                sfgets(tmp, 10, db.nsreg);
                i = atoi(tmp);
                for(i--;i;i--)
                  addNReg(tmp2);
        }
        fclose(db.nsreg);
}
Пример #15
0
void MainWindow::setSingnals()
{
    connect(fileMenuNew, SIGNAL(triggered()), this, SLOT( sNew() ));
    connect(fileMenuOpen, SIGNAL(triggered()), this, SLOT( sOpen() ));
    connect(fileMenuSave, SIGNAL(triggered()), this, SLOT( sSave() ));
    connect(fileMenuQuit, SIGNAL(triggered()), qApp, SLOT(quit() ));
    connect(fileMenuSaveAs, SIGNAL(triggered()), this, SLOT( sSaveAs() ));
    connect(this->ui->send_button, SIGNAL(clicked()), this, SLOT(sSend()));
    //connect(przyklad, SIGNAL(triggered()), this, SLOT( sEg((QString)"przyklad") ));
    connect(Run, SIGNAL(triggered()), this, SLOT( sRun() ));
    connect(Debug, SIGNAL(triggered()), this, SLOT( sDebug() ));
    connect(Stop, SIGNAL(triggered()), this, SLOT( sStop() ));

    connect(Undo, SIGNAL(triggered()), this, SLOT( sUndo() ));
    connect(Redo, SIGNAL(triggered()), this, SLOT( sRedo() ));

    connect(Copy, SIGNAL(triggered()), this, SLOT(sCopy()));
    connect(Cut, SIGNAL(triggered()), this, SLOT(sCut()));
    connect(Paste, SIGNAL(triggered()), this, SLOT(sPaste()));
    connect(toC, SIGNAL(triggered()), this, SLOT(sToC()));
    connect(toJava, SIGNAL(triggered()), this, SLOT(sToJava()));

}
Пример #16
0
/** 
 * \brief Loads the clone rule database from disk
 */
void readTriggerData(void)
{
	CloneRule *rule = NULL;
	char *command, *text;
	int done = 0;
	unsigned long linenum = 0;

	db.trigger = fopen(TRG_DB, "r");

	if (db.trigger == NULL) {
		logDump(corelog,
				"Unable to open trigger database for read access: %s",
				strerror(errno));
		return;
	}

	while (!done) {
		if (!(sfgets(dbLine, 2048, db.trigger))) {
			if (!done) {
				unexpected_eof(TRG_DB);
			}
			done = 1;
			fclose(db.trigger);
			return;
		}
		linenum++;

		if (parse_init(&state, dbLine) != 0) {
			/*! \bug XXX be nicer here... */
			abort();
		}

		command = parse_getarg(&state);

		if (strcmp(command, "Trigger") == 0) {
			rule = NewCrule();
			rule->kill_msg = NULL;
			rule->warn_msg = NULL;
			strncpyzt(rule->mask, parse_getarg(&state),
					  sizeof(rule->mask));
			rule->mask[sizeof(rule->mask) - 1] = '\0';
			rule->trigger = atoi(parse_getarg(&state));
			rule->utrigger = atoi(parse_getarg(&state));
			rule->flags = atol(parse_getarg(&state));
			AddCrule(rule, -2);	/* -2 is magic for append to end */
		} else if (strcmp(command, "Killmsg") == 0) {
			text = parse_getallargs(&state);
			if (text && rule)
				rule->kill_msg = strdup(text);
		} else if (strcmp(command, "Warnmsg") == 0) {
			text = parse_getallargs(&state);
			if (text && rule)
				rule->warn_msg = strdup(text);
		} else if (strcmp(command, "done") == 0) {
			done = 1;
		} else {
			fprintf(stderr, "Error in reading trigger data (%s) %lu\n",
					dbLine, linenum);
			parse_cleanup(&state);
			return;
		}
#ifdef DBDEBUG
		sSend(":%s PRIVMSG " DEBUGCHAN " :Read trigger data (%s)",
			  OperServ, dbLine);
#endif

		parse_cleanup(&state);
	}

	fclose(db.trigger);
}
Пример #17
0
/** 
 * \brief Loads the memo database from disk
 */
void readMemoData(void)
{
	RegNickList *nick = NULL;
	RegNickList *from, *rnlb;
	MemoList *newmemo;
	char *command;
	char *topic;
	int done = 0;
	unsigned long linenum = 0;

	db.ms = fopen(MS_DB, "r");

	if (db.ms == NULL)
		return;

	while (!done) {
		if (!(sfgets(dbLine, 2048, db.ms))) {
			if (!done) {
				unexpected_eof(MS_DB);
			}
			done = 1;
			fclose(db.ms);
			return;
		}

		linenum++;
		if (parse_init(&state, dbLine) != 0) {
			/*! \bug XXX be nicer here... */
			abort();
		}

		command = parse_getarg(&state);

		if (strcmp(command, "data") == 0) {
			nick = getRegNickData(parse_getarg(&state));
			/*! \bug Increment the arguments.. we REALLY need to fix the dbs */
			(void)parse_getarg(&state);
			(void)parse_getarg(&state);
			if (nick) {
				nick->memos->flags = atoi(parse_getarg(&state));
				nick->memos->max = atoi(parse_getarg(&state));
				if (nick->memos->max <= 0)
					nick->memos->max = MS_DEF_RCV_MAX;
			}
		} else if (strcmp(command, "mblock") == 0) {
			MemoBlock *mbitem;
			if (nick && nick->memos) {
				char *nickToBlock;

				if ((nickToBlock = parse_getarg(&state))
					&& (rnlb = getRegNickData(nickToBlock))) {

					mbitem = (MemoBlock *) oalloc(sizeof(MemoBlock));
					mbitem->blockId = rnlb->regnum;
					mbitem->next = nick->memos->firstMblock;
					nick->memos->firstMblock = mbitem;
				}
			}
		} else if (strcmp(command, "redirect") == 0) {
			nick = getRegNickData(parse_getarg(&state));
			if (nick != NULL)
				nick->memos->forward =
					getRegNickData(parse_getarg(&state));
		} else if (strcmp(command, "memo") == 0) {
			char *cn;

			cn = parse_getarg(&state);

			nick = getRegNickData(cn);
			if (nick == NULL) {
				printf("memo: %s not valid\n", cn);
				continue;
			}
			newmemo = (MemoList *) oalloc(sizeof(MemoList));
			newmemo->realto = nick;
			/*! \bug Increment the argument 1, we need to fix the db */
			(void)parse_getarg(&state);
			newmemo->flags = atoi(parse_getarg(&state));
			newmemo->sent = (time_t) atol(parse_getarg(&state));

			/* Memo expiration code */

			if ((time(NULL) - newmemo->sent) >= NICKDROPTIME
			     && !(newmemo->flags & MEMO_SAVE)) {
				FREE(newmemo);
				continue;
			}

			strncpyzt(newmemo->from, parse_getarg(&state), NICKLEN);
			from = getRegNickData(newmemo->from);
			strncpyzt(newmemo->to, parse_getarg(&state), CHANLEN);

			/* Read the memo, skipping the leading : */
			topic = parse_getallargs(&state);
			if (topic == NULL) {
				FREE(newmemo);
				continue;
			}
			newmemo->memotxt = strdup(topic);

			/* Add the memo to the users memobox */
			LIST_ENTRY_INIT(newmemo, ml_lst);
			LIST_INSERT_HEAD(&nick->memos->mb_memos, newmemo, ml_lst);
			if (from && newmemo->flags & MEMO_UNREAD)
				LIST_INSERT_HEAD(&from->memos->mb_sent, newmemo, ml_sent);
			nick->memos->memocnt++;
		} else if (strcmp(command, "done") == 0) {
			done = 1;
		} else {
			fprintf(stderr, "Error in reading memo data (%s) %lu\n",
					dbLine, linenum);
			sshutdown(-1);
		}
#ifdef DBDEBUG
		sSend(":%s PRIVMSG " DEBUGCHAN " :Read memo data (%s)", MemoServ,
			  dbLine);
#endif

		parse_cleanup(&state);
	}

	fclose(db.ms);
}
Пример #18
0
/** 
 * \brief Saves the Memo database to disk
 */
void saveMemoData(void)
{
	RegNickList *nl;
	MemoBox *tmp;
	MemoList *memo;
	MemoBlock *mbitem;
	const char *tmpNickName;
	int bucket;
	int totmemos;
	int totboxes;

	db.ms = fopen(MS_DB, "w");

	totmemos = 0;
	totboxes = 0;

	for (bucket = 0; bucket < NICKHASHSIZE; bucket++) {
		nl = LIST_FIRST(&RegNickHash[bucket]);

		while (nl != NULL) {
			tmp = nl->memos;
			if (tmp != NULL) {
				totboxes++;
				fprintf(db.ms, "data %s %i %i %i %i\n", nl->nick,
						tmp->memocnt, tmp->flags, tmp->flags, tmp->max);
				if (tmp->forward)
					fprintf(db.ms, "redirect %s %s\n", nl->nick,
							tmp->forward->nick);
				for (mbitem = tmp->firstMblock;
					 mbitem; 
					 mbitem = mbitem->next
				    )
				{
					if ((tmpNickName = mbitem->blockId.getNick()))
						fprintf(db.ms, "mblock %s\n", tmpNickName);
				}

				for (memo = LIST_FIRST(&tmp->mb_memos); memo;
					 memo = LIST_NEXT(memo, ml_lst)) {
					if (ShouldMemoExpire(memo, 0)) {
						memo = LIST_NEXT(memo, ml_lst);
						if (memo == NULL)
							break;
						continue;
					}
					fprintf(db.ms, "memo %s %i %i %lu %s %s :%s\n",
							nl->nick, 0, memo->flags, (long)memo->sent,
							memo->from, memo->to, memo->memotxt);
					totmemos++;
				}
			}
			nl = LIST_NEXT(nl, rn_lst);
		}
	}

	fprintf(db.ms, "done\n");

	fclose(db.ms);

	sSend(":%s PRIVMSG " LOGCHAN " :Completed save(%u boxes, %u memos)",
		  MemoServ, totboxes, totmemos);
}
Пример #19
0
/** 
 * \brief Loads the ChanServ database from disk
 */
void readChanData()
{
	RegChanList *rcl;
	RegNickList *rnl;
	char *command;
	int done = 0, db_version = 1;
	int line_num = 0;
	char *pass;
	char *topic;

	rcl = NULL;
	rnl = NULL;
	db.cs = fopen(CS_DIR "chanserv.db", "r");
	if (db.cs == NULL)
		return;

	while (!done) {
		if ((sfgets(dbLine, 2048, db.cs)) == 0) {
			if (!done) {
				unexpected_eof(CS_DB);
			}
			done = 1;
			fclose(db.cs);
			return;
		}
		line_num++;

		if (parse_init(&state, dbLine) != 0) {
			fprintf(stderr,
					CS_DIR "chanserv.db:%d: " " Fatal error during read "
					" (Null line?) \n", line_num);
			abort();
		}

		command = parse_getarg(&state);
		if (!strcmp(command, "version")) {
			db_version = atoi(parse_getarg(&state));
		}
		else if (!strcmp(command, "channel")) {
			char *sChannelName, *sFounderNick;

			rcl = (RegChanList *) oalloc(sizeof(RegChanList));
			sChannelName = parse_getarg(&state);
			sFounderNick = parse_getarg(&state);
			initRegChanData(rcl);

			if (strlen(sChannelName) >= CHANLEN) {
				fprintf(stderr,
						CS_DIR "chanserv.db:%d: "
						" Channel name '%.80s' exceeds " " CHANLEN.\n",
						line_num, sChannelName);
				sshutdown(-1);
			} else if (strlen(sFounderNick) >= NICKLEN) {
				fprintf(stderr,
						CS_DIR "chanserv.db:%d: "
						" Founder nick name '%.80s' " " (%.80s)"
						" exceeds NICKLEN.\n", line_num, sFounderNick,
						sChannelName);
				sshutdown(-1);
			}

			if (!sChannelName || !sFounderNick) {
				fprintf(stderr,
						CS_DIR "chanserv.db:%d: " " Parse error. (%p, %p)",
						line_num, sChannelName, sFounderNick);
				sshutdown(-1);
			}

			rnl = getRegNickData(sFounderNick);

			strcpy(rcl->name, sChannelName);

			if (rnl)
			{
				rcl->founderId = rnl->regnum;
				rnl->chans++;
			}
			else
				rcl->founderId = RegId(0, 0);

			rcl->mlock = atol(parse_getarg(&state));
			rcl->flags = atol(parse_getarg(&state));
			pass = parse_getarg(&state);	/*! \bug XXX verify this works */
			if (!pass) {
				fprintf(stderr,
						CS_DIR "chanserv.db:%d: " " Null password?!",
						line_num);
				sshutdown(-1);
			} 

			if ((db_version < 2) || *pass == '@') {
				if (db_version < 2)
					strcpy((char *)rcl->password, pass);
				else
					strcpy((char *)rcl->password, pass + 1);

				if (strlen(pass) > (u_int)((db_version < 2) ? PASSLEN : PASSLEN+1)) {
					fprintf(stderr,
							CS_DIR "chanserv.db:%d: " " password > PASSLEN",
							line_num);
					sshutdown(-1);
				}

				xorit((char *)rcl->password);
				rcl->flags &= ~CENCRYPT;
			}
			else {
				u_char *tmpup = fromBase64(pass+1, NULL);
				int q;

				if (!tmpup)
					abort();
				for(q = 0; q < 16; q++)
					rcl->password[q] = tmpup[q];
				FREE(tmpup);
				rcl->flags |= CENCRYPT;
			}

			rcl->timereg = (time_t) atol(parse_getarg(&state));
			rcl->timestamp = (time_t) atol(parse_getarg(&state));
			strncpyzt(rcl->key, parse_getarg(&state), KEYLEN);
			rcl->limit = atol(parse_getarg(&state));
			rcl->memolevel = atoi(parse_getarg(&state));
			rcl->tlocklevel = atoi(parse_getarg(&state));
			rcl->restrictlevel = atoi(parse_getarg(&state));
			/* The rest of the line - skipping the leading : */
			topic = parse_getallargs(&state);
			if (topic == NULL)
				rcl->desc[0] = '\0';
			else
				strncpyzt(rcl->desc, topic, CHANDESCBUF);
			addRegChan(rcl);
			mostchans++;
		} else if (!strcmp(command, "topic")) {
			rcl = getRegChanData(parse_getarg(&state));
			if (rcl == NULL)
				continue;
			strncpyzt(rcl->tsetby, parse_getarg(&state), NICKLEN);
			rcl->ttimestamp = (time_t) atol(parse_getarg(&state));
			/* The rest of the topic, skipping the : in it */
			topic = parse_getallargs(&state);
			if (topic == NULL)
				rcl->topic = NULL;
			else
				rcl->topic = strdup(topic);
		} else if (!strcmp(command, "url")) {
			rcl = getRegChanData(parse_getarg(&state));
			if (rcl == NULL)
				continue;
			topic = parse_getallargs(&state);
			if (topic == NULL)
				rcl->url = NULL;
			else
				rcl->url = strdup(topic);
		} else if (!strcmp(command, "autogreet")) {
			rcl = getRegChanData(parse_getarg(&state));
			if (rcl == NULL)
				continue;
			topic = parse_getallargs(&state);
			if (topic == NULL)
				rcl->autogreet = NULL;
			else
				rcl->autogreet = strdup(topic);
		} else if (!strcmp(command, "markby")) {
			rcl = getRegChanData(parse_getarg(&state));
			if (rcl == NULL)
				continue;
			topic = parse_getarg(&state);
			if (topic == NULL)
				rcl->markby = NULL;
			else
				rcl->markby = strdup(topic);
		} else if (strcmp(command, "chkey") == 0) {
			char *tmpp = parse_getarg(&state);
			if (rcl && tmpp)
				rcl->chpw_key = strtoul(tmpp, (char **)0, 16);
		} else if (!strcmp(command, "op")) {
			cAccessList *lame;
			char *tmpName;

			rcl = getRegChanData(parse_getarg(&state));
			if (rcl == NULL)
				continue;
			tmpName = parse_getarg(&state);
			if ((rnl = getRegNickData(tmpName)) != NULL)
			{
				lame = (cAccessList *) oalloc(sizeof(cAccessList));
				lame->nickId = rnl->regnum;
				lame->uflags = atoi(parse_getarg(&state));
				addChanOp(rcl, lame);
			}
		} else if (!strcmp(command, "akick")) {
			cAkickList *lame;
			lame = (cAkickList *) oalloc(sizeof(cAkickList));
			rcl = getRegChanData(parse_getarg(&state));
			if (rcl == NULL)
				continue;
			strncpyzt(lame->mask, parse_getarg(&state), 70);
			lame->added = (time_t) atol(parse_getarg(&state));
			/* The rest of the string... */
			topic = parse_getallargs(&state);
			if (topic == NULL)
				lame->reason[0] = '\0';
			else {
				strncpyzt(lame->reason, topic, NICKLEN + 50);
			}
			addChanAkick(rcl, lame);
		} else if (!strcmp(command, "done"))
			done = 1;
		else {
			fprintf(stderr, "GLOBOPS :Read chan data (%s)", dbLine);
			sshutdown(-1);
		}

#ifdef DBDEBUG
		sSend(":%s PRIVMSG " DEBGUGCHAN " :Read chan data (%s)", ChanServ,
			  dbLine);
#endif

		parse_cleanup(&state);
	}
	fclose(db.cs);
}
Пример #20
0
/** 
 * \brief Saves the ChanServ database to disk
 */
void saveChanData(RegChanList * first)
{
	RegChanList *cl = first;
	cAccessList *accitem;
	cAkickList *akitem;
	const char *tmpFounderNick;
	int x = 0;

	saveChanUrls(first);
	db.cs = NULL;
	db.cs = fopen(CS_DIR "chanserv.db", "w");
	if (db.cs == NULL) {
		sSend(":%s GOPER :ERROR: Unable to save Channel database fopen failed: %s", myname, strerror(errno));
		logDump(corelog, "Unable to save Channel database: fopen: %s", strerror(errno));
		return;
	}

	fprintf(db.cs, "version 2\n");

	while (cl) {
		tmpFounderNick = cl->founderId.getNick();

		if (tmpFounderNick == NULL)
			tmpFounderNick = "-";

		/* New chan insertion point */
		fprintf(db.cs, "channel ");
		fprintf(db.cs, "%s %s ", cl->name, tmpFounderNick);
		fprintf(db.cs, "%lu %lu ", cl->mlock, cl->flags);

		if (!(cl->flags & CENCRYPT)) {
			strcpy(cryptstr, (char *)cl->password);
			xorit(cryptstr);
			fprintf(db.cs, "@%s ", cryptstr);
		}
		else {
			u_char *tmpup = toBase64(cl->password, 16);
			if (!tmpup)
				abort();
			fprintf(db.cs, "$%s ", tmpup);
			FREE(tmpup);
		}

		fprintf(db.cs, "%lu ", (unsigned long)cl->timereg);
		fprintf(db.cs, "%lu ", (unsigned long)cl->timestamp);
		fprintf(db.cs, "%s %lu %i ", cl->key, cl->limit, cl->memolevel);
		fprintf(db.cs, "%i %i :%s\n", cl->tlocklevel, cl->restrictlevel,
				cl->desc);
		if (cl->topic)
			fprintf(db.cs, "topic %s %s %lu :%s\n", cl->name, cl->tsetby,
					cl->ttimestamp, cl->topic);
		if (cl->url)
			fprintf(db.cs, "url %s :%s\n", cl->name, cl->url);
		if (cl->autogreet != NULL)
			fprintf(db.cs, "autogreet %s :%s\n", cl->name, cl->autogreet);
		if ((cl->flags & CMARK) && cl->markby)
			fprintf(db.cs, "markby %s %s\n", cl->name, cl->markby);
		if (cl->chpw_key)
			fprintf(db.cs, "chkey %X\n", cl->chpw_key);
		if (cl->firstOp) {
			const char *tmpName;

			for (accitem = cl->firstOp; accitem; accitem = accitem->next) {
				tmpName = (accitem->nickId).getNick();

				if (tmpName == NULL)
				    continue;
				fprintf(db.cs, "op %s %s ", cl->name, tmpName);
				fprintf(db.cs, "%i\n", accitem->uflags);
			}
		}

		if (cl->firstAkick) {
			for (akitem = cl->firstAkick; akitem; akitem = akitem->next) {
				fprintf(db.cs, "akick %s %s ", cl->name, akitem->mask);
				fprintf(db.cs, "%lu :%s\n", (u_long) akitem->added,
						akitem->reason);
			}
		}
		x++;
		fflush(db.cs);
#ifdef DBDEBUG
		sSend(":%s PRIVMSG " DEBUGCHAN " :Saved chan data (%s)", ChanServ,
			  cl->name);
#endif
		cl = cl->next;
	}
	fprintf(db.cs, "done\n");
	fflush(db.cs);
	fclose(db.cs);
#ifdef GLOBOPS_TIMED_MSGS
	sSend(":%s GLOBOPS :Completed save(%i)", ChanServ, x);
#else
	sSend(":%s PRIVMSG " LOGCHAN " :Completed save(%i)", ChanServ, x);
#endif
}
Пример #21
0
/**
 * \brief Loads the NickServ database from disk
 */
void readNickData()
{
	RegNickList *rnl = NULL;
	char *command, *tmpp;
	unsigned char *tmpup;
	int done = 0, db_version = 1;
	int line_num = 0, do_enc = 0;

#ifdef REQ_EMAIL
	readRegData();
#endif

	db.ns = fopen(NS_DB, "r");

	if (db.ns == NULL) {
		logDump(corelog, "Unable to open " NS_DB ": %s", strerror(errno));
		return;
	}

	while (!done) {
		if (!(sfgets(dbLine, 1024, db.ns))) {
			if (!done) {
				unexpected_eof(NS_DB);
			}
			done = 1;
			fclose(db.ns);
			return;
		}

		line_num++;

		if (parse_init(&state, dbLine) != 0) {
			/*! \bug XXX make a nicer error here! */
			abort();
		}

		command = parse_getarg(&state);
		if (strcmp(command, "version") == 0) {
			tmpp = parse_getarg(&state);
			assert(tmpp);

			if (tmpp)
				db_version = atoi(tmpp);
		}
		else
		if (strcmp(command, "nick") == 0) {
			rnl = (RegNickList *) oalloc(sizeof(RegNickList));
			char *sNick, *sUser, *sHost, *sPass;

			sNick = parse_getarg(&state);
			sUser = parse_getarg(&state);
			sHost = parse_getarg(&state);
			sPass = parse_getarg(&state);

			if (strlen(sNick) >= NICKLEN) {
				fprintf(stderr,
						NS_DB ":%d: " " Nickname '%.80s' exceeds "
						" NICKLEN.\n", line_num, sNick);
				sshutdown(-1);
			} 

			strcpy(rnl->nick, sNick);
			strncpyzt(rnl->user, sUser, USERLEN);
			SetDynBuffer(&rnl->host, sHost);

			if (db_version < 2)
			{
				if (strlen(sPass) > PASSLEN) {
					fprintf(stderr,
						NS_DB ":%d: " " Password for nick '%s' "
						" exceeds PASSLEN.\n", line_num, sNick);
					sshutdown(-1);
				}

				strcpy((char *)rnl->password, xorit(sPass));
			}
			else {
				char encType = *sPass;

				if (encType == '@') {
					if (strlen(sPass+1) > PASSLEN) {
						fprintf(stderr,
							NS_DB ":%d: " " Password for nick '%s' "
							" exceeds PASSLEN.\n", line_num, sNick);
						sshutdown(-1);
					}

					strcpy((char *)rnl->password, xorit(sPass + 1));
					do_enc = 0;
				}
				else if (encType == '$') {
					int q, len;

					tmpup = fromBase64(sPass + 1, &len);
					assert(tmpup);

					for(q = 0; q < 16; q++)
						rnl->password[q] = tmpup[q];
					do_enc = 1;
					FREE(tmpup);
				}
				else
					rnl->password[0] = '\0';
			}

			rnl->timestamp = (time_t) atol(parse_getarg(&state));
			rnl->timereg = (time_t) atol(parse_getarg(&state));
			rnl->flags = atoi(parse_getarg(&state));

			if (db_version >= 3) {
				const char *idString = parse_getarg(&state);
				int av, bv;

				sscanf(idString, "%X*%X", &av, &bv);
				rnl->regnum.SetDirect(top_regnick_idnum, av, bv);				
			}
			else {
				rnl->regnum.SetNext(top_regnick_idnum);
			}

			if (do_enc)
				rnl->flags |= NENCRYPT;
			else
				rnl->flags &= ~NENCRYPT;

			rnl->opflags = 0;
			rnl->idtime = DEF_NDELAY;
			ADD_MEMO_BOX(rnl);
			addRegNick(rnl);
		} else if (strcmp(command, "is") == 0) {
			char *data = parse_getarg(&state);
			if (rnl && data)
				rnl->is_readtime = atol(data);
		} else if (strcmp(command, "oper") == 0) {
			char *opflags_s;
			if (rnl && (rnl == getRegNickData(parse_getarg(&state)))) {
				if ((opflags_s = parse_getarg(&state)))
					rnl->opflags |=
						(strtoul(opflags_s, (char **)0, 10) &
						 ~(OROOT | OSERVOP));
				if (rnl->opflags)
					addOpData(rnl);
			}
		} else if (strcmp(command, "url") == 0) {
			if (rnl && (rnl == getRegNickData(parse_getarg(&state))))
			{
				rnl->url = strdup(parse_getarg(&state));
				if (strlen(rnl->url) > (URLLEN - 1))
					rnl->url[URLLEN - 1] = '\0';
			}
		} else if (strcmp(command, "gecos") == 0) {
#ifdef TRACK_GECOS
			char *gecos = parse_getallargs(&state);
			if (gecos != NULL)
				rnl->gecos = strdup(gecos);
#endif
		} else if (strcmp(command, "akey") == 0) {
#ifdef REQ_EMAIL
			if (rnl)
				rnl->email_key = atoi(parse_getarg(&state));
#endif
		} else if (strcmp(command, "chkey") == 0) {
			char *tmpp = parse_getarg(&state);
			if (rnl && tmpp)
				rnl->chpw_key = strtoul(tmpp, (char **)0, 16);
		} else if (strcmp(command, "markby") == 0) {
			char *mby;

			rnl = getRegNickData(parse_getarg(&state));
			if (!rnl || !(mby = parse_getarg(&state)))
				continue;
			rnl->markby = strdup(mby);
		} else if (strcmp(command, "access") == 0) {
			rnl = getRegNickData(parse_getarg(&state));
			addAccItem(rnl, parse_getarg(&state));
		} else if (!strcmp(command, "email")) {
			rnl = getRegNickData(parse_getarg(&state));

			strncpyzt(rnl->email, parse_getarg(&state), EMAILLEN);

			if (!strcmp(rnl->email, "(none)"))
				strcat(rnl->email, " ");
		} else if (!strcmp(command, "idtime")) {
			rnl = getRegNickData(parse_getarg(&state));
			rnl->idtime = atoi(parse_getarg(&state));
		} else if (!strcmp(command, "done"))
			done = 1;
		else {
			fprintf(stderr, NS_DB ":%d: Error reading nick data (%s)",
					line_num, dbLine);
			sshutdown(-1);
		}
#ifdef DBDEBUG
		sSend(":%s PRIVMSG " DEBUGCHAN " :Read nick data (%s)", NICKSERV,
			  dbLine);
#endif

		parse_cleanup(&state);
	}
	fclose(db.ns);

	readMemoData();
}
Пример #22
0
/** 
 * \brief Saves the NickServ database to disk
 */
void saveNickData(void)
{
	RegNickList *nl;
	nAccessList *accitem;
	int x = 0, bucket;

	db.ns = fopen(NS_DB, "w");

	if (db.ns == NULL) {
		sSend(":%s GOPER :ERROR: Unable to save NickServ database fopen failed: %s", myname, strerror(errno));
		logDump(corelog, "Unable to save NickServ database: fopen: %s", strerror(errno));
		return;
	}

	fprintf(db.ns, "version 3\n");

	for (bucket = 0; bucket < NICKHASHSIZE; bucket++) {
		nl = LIST_FIRST(&RegNickHash[bucket]);
		while (nl != NULL) {
			/* New nick insertion point */
			fprintf(db.ns, "nick ");
			if (nl->user[0] == '\0')
				fprintf(db.ns, "%s . %s ", nl->nick, nl->host);
			else
				fprintf(db.ns, "%s %s %s ", nl->nick, nl->user, nl->host);

			if (!(nl->flags & NENCRYPT))
			{
				strcpy(cryptstr, (char *)nl->password);
				xorit(cryptstr);
				fprintf(db.ns, "@%s ", cryptstr);
			}
			else {
				unsigned char *p;

				// XXX Put note that PASSLEN must be at least 15
				p = toBase64(nl->password, 16);
				fprintf(db.ns, "$%s ", p);
				FREE(p);
			}

			fprintf(db.ns, "%lu ", (unsigned long)nl->timestamp);
			fprintf(db.ns, "%lu ", (unsigned long)nl->timereg);
			fprintf(db.ns, "%i %X*%X\n", nl->flags, nl->regnum.a, nl->regnum.b);

			/* Infoserv data */
			fprintf(db.ns, "is %ld\n", nl->is_readtime);

#ifdef REQ_EMAIL
			if (!(nl->flags & NACTIVE) || (nl->flags & NDEACC))
				fprintf(db.ns, "akey %lu\n", nl->email_key);
#endif
			if (nl->chpw_key)
				fprintf(db.ns, "chkey %X\n", nl->chpw_key);
			if (nl->url != NULL)
				fprintf(db.ns, "url %s %s\n", nl->nick, nl->url);
#ifdef TRACK_GECOS
			if (nl->gecos != NULL)
				fprintf(db.ns, "gecos :%s\n", nl->gecos);
#endif

			if (nl->email[0] && strcmp(nl->email, "(none)"))
				fprintf(db.ns, "email %s %s\n", nl->nick, nl->email);

			if ((nl->opflags & ~(OROOT | OSERVOP)))
				fprintf(db.ns, "oper %s %lu 0 0\n", nl->nick, nl->opflags);

			if ((nl->flags & NMARK) && nl->markby)
				fprintf(db.ns, "markby %s %s\n", nl->nick, nl->markby);

			if (nl->idtime != DEF_NDELAY)
				fprintf(db.ns, "idtime %s %i\n", nl->nick, nl->idtime);

			for (accitem = LIST_FIRST(&nl->acl); accitem;
				 accitem = LIST_NEXT(accitem, al_lst))
				fprintf(db.ns, "access %s %s\n", nl->nick, accitem->mask);
			x++;
			fflush(db.ns);
#ifdef DBDEBUG
			sSend(":%s PRIVMSG " DEBUGCHAN " :Saved nick data (%s)",
				  NickServ, nl->nick);
#endif
			nl = LIST_NEXT(nl, rn_lst);
		}
	}
	fprintf(db.ns, "done\n");
	fflush(db.ns);
	fclose(db.ns);
#ifdef GLOBOPS_TIMED_MSGS
	sSend(":%s GLOBOPS :Completed save(%i)", NickServ, x);
#else
	sSend(":%s PRIVMSG " LOGCHAN " :Completed save(%i)", NickServ, x);
#endif
}
Пример #23
0
/*
 * WARNING WARNING WARNING
 *
 *  This function is very ugly in terms of args handling, and it is
 *  very easy to inadvertently break something if you make small tweaks
 *  to it.
 *
 *  args and numargs do NOT always map together in this function,
 *  for example numargs = 3, means that args really has 3+3=6 elements
 *  in some points: numargs should be numargs2.
 *
 *  Basically, the bottom two elements of args[] are dropped
 * in this function when
 * it goes to args2 to call the particular handlers -Mysid
 */
void
parseLine(char *line)
{
	int i = 0, a = 0, x = 0, prefixed = 0;
	char *args2[MAX_IRC_LINE_LEN + 5];
	char *args[MAX_IRC_LINE_LEN + 5];
	char realargs[151][151];
	u_int16_t numargs = 0;
	/* 
	 * Seems Ok to me ^^^ 
	 * sizes may be off(?)
	 */

	/* Yes, your sizes were off.. -Mysid */

	strncpyzt(coreBuffer, line, MAX_IRC_LINE_LEN);
#ifdef DEBUG
	printf("Read: %s\n", coreBuffer);
#endif

	CTime = time(NULL);

	while (*line && x < 150) {
		while (*line != ' ' && *line && a < 150) {
			realargs[x][a] = *line;
			a++;
			line++;
		}
		realargs[x][a] = 0;
		args[x] = realargs[x];
		x++;
		numargs++;
		while (*line == ' ')
			line++;
		a = 0;
	}

	/* ensure the next item is null so we can check it later */
	realargs[x][0] = 0;
	args[x] = realargs[x];

	if (args[0][0] == ':') {
		prefixed = 1;
				 /** \bug old lame bugfix, what would be better is to use a 'from'
                    value and args++'ing it, if there's no prefix then
                    have from set to the uplink -Mysid */
		args[0]++;
	} else
		prefixed = 0;

	if (!strcmp(args[0], "PING") && !prefixed) {
		sSend("PONG :%s", myname);
		return;
	}

	else if (!strcmp(args[0], "ERROR") && !strcmp(args[1], ":Closing"))
		sshutdown(0);

	else if (!strcmp(args[0], "NICK") && !prefixed) {
		if (strchr(args[4], '*') || strchr(args[4], '?')
			|| strchr(args[4], '!') || strchr(args[4], '@')) {
			char nick[NICKLEN];

			strncpyzt(nick, args[1], NICKLEN);
			sSend
				(":%s KILL %s :%s!%s (Your ident reply contains either a *, !, @, or ?. Please remove this before returning.)",
				 services[1].name, nick, services[1].host,
				 services[1].name);
			addGhost(nick);
			timer(15, delTimedGhost, strdup(nick));
			return;
		}

		addNewUser(args, numargs);	/* nickserv.c, add new user. */
		return;
	}


	if (!strcmp(args[1], "PRIVMSG")) {
		UserList *tmp = getNickData(args[0]);


		if (strchr(args[2], '#') || strchr(args[2], '$'))
			return;

		if (!strcasecmp(args[0], NickServ)
			|| !strcasecmp(args[0], GameServ)
			|| !strcasecmp(args[0], OperServ)
			|| !strcasecmp(args[0], ChanServ)
			|| !strcasecmp(args[0], MemoServ)
			|| !strcasecmp(args[0], InfoServ)) return;

		if (tmp && tmp->reg && tmp->reg->flags & NBANISH) {
			sSend(":%s NOTICE %s :This nickname is banished."
			      "  You cannot use services until you change"
			      " nicknames.",
			      NickServ, args[0]);
			return;
		}

		if (!tmp) {
			nDesynch(args[0], "PRIVMSG");
			return;
		}

		if (addFlood(tmp, 1))
			return;

		if (getBanInfo(tmp->nick, tmp->user, tmp->host, A_IGNORE) != NULL) {
			if (tmp->floodlevel.GetLev() < 2)
				sSend
					(":%s NOTICE %s :You are on services ignore, you may not use any Service",
					 NickServ, tmp->nick);
			if (!isOper(tmp) || tmp->caccess < ACC_RECOGNIZED || !tmp->reg
				|| !(tmp->reg->opflags & OROOT))
				return;
		}

		args[3]++;
		while (*args[3] == ' ')
			args[3]++;

		for (i = 3; i < numargs; i++)
			args2[i - 3] = args[i];
		numargs -= 3;

		/* Handle pings before even going to the services */
		if (!strcasecmp(args2[0], "\001PING")) {
			if (addFlood(tmp, 3))
				return;
			if (numargs < 3)
				sSend(":%s NOTICE %s :\001PING %s", args[2], args[0],
					  args2[1]);
			else
				sSend(":%s NOTICE %s :\001PING %s %s", args[2], args[0],
					  args2[1], args2[2]);
			return;
		}

		/* NOTE: numargs maps to args2 not args at this point */
		if (!strncasecmp(args[2], OperServ, strlen(OperServ)))
			sendToOperServ(tmp, args2, numargs);
		else if (!strncasecmp(args[2], NickServ, strlen(NickServ)))
			sendToNickServ(tmp, args2, numargs);
		else if (!strncasecmp(args[2], ChanServ, strlen(ChanServ)))
			sendToChanServ(tmp, args2, numargs);
		else if (!strncasecmp(args[2], MemoServ, strlen(MemoServ)))
			sendToMemoServ(tmp, args2, numargs);
		else if (!strncasecmp(args[2], InfoServ, strlen(InfoServ)))
			sendToInfoServ(tmp, args2, numargs);
		else if (!strncasecmp(args[2], GameServ, strlen(GameServ)))
			sendToGameServ(tmp, args2, numargs);
		else if (isGhost(args[2])) {
			sSend
				(":%s NOTICE %s :This is a NickServ registered nick enforcer, and not a real user.",
				 args[2], args[0]);
		}
		/* Note, the below should be correct. */
		else if ((numargs >= 1) && adCheck(tmp, args[2], args2, numargs))
			return;
		return;
	}

	else if (!strcmp(args[1], "QUIT")) {
		remUser(args[0], 0);
		return;
	} else if (!strcmp(args[1], "NICK")) {
		UserList *tmp = getNickData(args[0]);
		if (addFlood(tmp, 5))
			return;
		changeNick(args[0], args[2], args[3]);
		return;
	} else if (!strcmp(args[1], "MODE") && !strcmp(args[0], args[2])) {
		setMode(args[0], args[3]);
		return;
	} else if (!strcmp(args[1], "MODE")) {
		setChanMode(args, numargs);
		return;
	} else if (!strcmp(args[1], "TOPIC")) {
		setChanTopic(args, numargs);
		return;
	} else if (!strcmp(args[1], "AWAY")) {
		if (numargs < 3) {
			setFlags(args[0], NISAWAY, '-');
			checkMemos(getNickData(args[0]));
		} else
			setFlags(args[0], NISAWAY, '+');
		return;
	}

	else if (!strcmp(args[1], "JOIN")) {
		addUserToChan(getNickData(args[0]), args[2]);
		return;
	} else if (!strcmp(args[1], "PART")) {
		remUserFromChan(getNickData(args[0]), args[2]);
		return;
	} else if (!strcmp(args[1], "KICK")) {
		remUserFromChan(getNickData(args[3]), args[2]);
		return;
	}

	else if (!strcmp(args[1], "KILL")) {
		int i;
		for (i = 0; i < NUMSERVS; i++) {
			if (!strcasecmp(args[2], services[i].name)) {
				addUser(services[i].name, services[i].uname,
						services[i].host, services[i].rname,
						services[i].mode);
				sSend(":%s KILL %s :%s!%s (services kill protection)",
					  services[i].name, args[0], services[i].host,
					  services[i].name);
				sSend(":%s GLOBOPS :%s just killed me!", services[i].name,
					  args[0]);
				remUser(args[0], 0);
				return;
			}
		}

		if (isGhost(args[2])) {
			delGhost(args[2]);
			return;
		}

		else
			remUser(args[2], 1);
		return;
	} else if (!strcmp(args[1], "MOTD")) {
		UserList *tmp = getNickData(args[0]);
		if (addFlood(tmp, 1))
			return;
		motd(args[0]);
		return;
	}

	else if (!strcmp(args[1], "INFO")) {
		UserList *tmp = getNickData(args[0]);
		if (!tmp || addFlood(tmp, 3))
			return;
		sendInfoReply(tmp);
		return;
	}

	else if (!strcmp(args[1], "VERSION")) {
		UserList *tmp = getNickData(args[0]);
		if (addFlood(tmp, 1))
			return;
		sSend(":%s 351 %s %s %s :%s", myname, args[0], VERSION_STRING,
			  myname, VERSION_QUOTE);
		return;
	} else if ((!strcmp(args[1], "GNOTICE") || !strcmp(args[1], "GLOBOPS"))
			   && !strcmp(args[2], ":Link") && !strcmp(args[3], "with")
			   && !strncmp(args[4], myname, strlen(myname))) {
		sSend(":%s GNOTICE :Link with %s[services@%s] established.",
			  myname, args[0], hostname);
		strncpyzt(hostname, args[0], sizeof(hostname));

		expireNicks(NULL);
		expireChans(NULL);
		sync_cfg("1");
		checkTusers(NULL);
		flushLogs(NULL);
		nextNsync = (SYNCTIME + CTime);
		nextCsync = ((SYNCTIME * 2) + CTime);
		nextMsync = ((SYNCTIME * 3) + CTime);
		loadakills();
		return;
	}
#ifdef IRCD_HURTSET
	else if (!strcmp(args[1], "HURTSET") && (numargs >= 4)) {
		UserList *hurtwho;
		if ((hurtwho = getNickData(args[2]))) {
			if (args[3] && *args[3] == '-')
				hurtwho->oflags &= ~(NISAHURT);
			else if (args[3] && atoi(args[3]) == 4) {
				hurtwho->oflags |= (NISAHURT);
			}
			else if (args[3] && isdigit(*args[3])
					 && (getBanInfo(hurtwho->nick, hurtwho->user,
							hurtwho->host, A_AHURT) != NULL)) 
			    hurtwho->oflags |= (NISAHURT);
		}
	}
#endif
	else if (!strcmp(args[1], "SQUIT")) {
		time_t jupe;
		jupe = time(NULL);
		if (strchr(args[2], '.'))
			return;
		sSend(":%s WALLOPS :%s Un-jupitered by %s at %s", myname, args[2],
			  args[0], ctime(&(jupe)));
		return;
	}

	else if (!strcmp(args[1], "STATS") && numargs > 3) {
		const char* from = args[0];

		if (args[2] && !strcasecmp(args[2], "OPTS"))
		{
			sSend(":%s NOTICE %s :Network name: %s", InfoServ, from, NETWORK);


#ifdef AKILLMAILTO
		        sSend(":%s NOTICE %s :Akill log address: %s", InfoServ, from,
		                AKILLMAILTO);
#endif

#ifdef ENABLE_GRPOPS
		        sSend(":%s NOTICE %s :GRPops enabled.",  InfoServ, from);
#endif

#ifdef MD5_AUTH
		        sSend(":%s NOTICE %s :MD5 authentication available.",  InfoServ, from);
#endif

		}
		else if (args[2] && !strcasecmp(args[2], "V$"))
		{
			sSend(":%s NOTICE %s :Based on sn services1.4.", InfoServ, from);
		}
	}

	/* "No N-line" error */
	else if (!strcmp(args[0], "ERROR") && !strcmp(args[1], ":No")) {
		fprintf(stderr, "Error connecting to server: No N-line\n");
		sshutdown(2);
	}
}
Пример #24
0
/**
 * Break up a string of data into seperate pieces and parse those.
 * (parseLine())
 * \bug "I'm not sure but this function could be done better(?) if someone
 *       wants to improve it..."
 */
void
breakLine(char *tmpbuffer)
{
	int usedbuf, terminated;
	char sendBuffer[MAX_IRC_LINE_LEN + 1];

	memset(sendBuffer, 0, MAX_IRC_LINE_LEN + 1);

	usedbuf = 0;

	/* Just in case the impossible happens, and our old data is >= 512 chars,
	 * which means we won't be able to add anything from the data stream, and
	 * therefore can't get the terminating \r\n
	 */
	if (strlen(oldData) >= MAX_IRC_LINE_LEN) {
		sSend(":%s GLOBOPS :Infinate loop encounted in breakLine().  "
			  "Mail this line to [email protected]", OperServ);
		sSend(":%s GLOBOPS :Services terminating", OperServ);
		sshutdown(1);
	}

	/* If we have some leftover unterminated data from the stream... */
	if (oldData[0] != '\0') {
		strncpyzt(sendBuffer, oldData, MAX_IRC_LINE_LEN);
		bzero(oldData, MAX_IRC_LINE_LEN);
		usedbuf = strlen(sendBuffer);
	}

	while (*tmpbuffer) {
		terminated = FALSE;

		/* While each of the following are true:
		 * @ We've not found a terminator
		 * @ We're not at the end of the buffer
		 * @ We're not at the end of the buffer we can copy to
		 */
		while (*tmpbuffer != '\n' && *tmpbuffer != '\r'
			   && *tmpbuffer != '\0' && usedbuf < MAX_IRC_LINE_LEN) {
			sendBuffer[usedbuf] = *tmpbuffer;
			usedbuf++;
			tmpbuffer++;
		}

		sendBuffer[usedbuf] = 0;
		usedbuf = 0;

		/* Clear trailing terminator */
		while (*tmpbuffer == '\r' || *tmpbuffer == '\n') {
			tmpbuffer++;
			terminated = TRUE;
		}

		if (terminated == FALSE) {	/* If we didn't find the terminators */
			/*
			 * Copy our current unfinished line to a tmp buffer, we'll look
			 * at it again in the next call to breakLine(), when we recieve
			 * more data.  Had to be done due to recv() taking unteminated
			 * data.
			 */
			strncpyzt(oldData, sendBuffer, MAX_IRC_LINE_LEN);
		} else {
			/* If we've got all our data, and it's terminated, we can parse it */
			parseLine(sendBuffer);
		}
	}
}