Ejemplo n.º 1
0
void lua_startbot(void *arg) {
  channel *cp;

  myureconnect = NULL;

  if(!luabotnick)
    luabotnick = getcopyconfigitem("lua", "botnick", "U", NICKLEN);

  lua_nick = registerlocaluser(luabotnick->content, "lua", "quakenet.department.of.corrections", LUA_FULLVERSION, "U", UMODE_ACCOUNT | UMODE_DEAF | UMODE_OPER | UMODE_SERVICE, &lua_bothandler);
  if(!lua_nick) {
    myureconnect = scheduleoneshot(time(NULL) + 1, &lua_startbot, NULL);
    return;
  }

  cp = findchannel(LUA_OPERCHAN);
  if(cp && localjoinchannel(lua_nick, cp)) {
    localgetops(lua_nick, cp);
  } else {
    localcreatechannel(lua_nick, LUA_OPERCHAN);
  }

  cp = findchannel(LUA_PUKECHAN);
  if(cp && localjoinchannel(lua_nick, cp)) {
    localgetops(lua_nick, cp);
  } else {
    localcreatechannel(lua_nick, LUA_PUKECHAN);
  }

  myublip = schedulerecurring(time(NULL) + 1, 0, 60, &lua_blip, NULL);
  myutick = schedulerecurring(time(NULL) + 1, 0, 1, &lua_tick, NULL);

  lua_registerevents();
}
Ejemplo n.º 2
0
static int pc_join(char *name) {
  patrolchannel *pc = NULL;
  channel *cp;

  for (pc = patrolchannels; pc; pc = pc->next)
    if (ircd_strcmp(pc->channel->content, name) == 0)
      return 0;

  cp = findchannel(name);

  if (!cp)
    return -1;

  pc = malloc(sizeof(patrolchannel));

  pc->channel = getsstring(name, 512);
  pc->nick = NULL;

  pc->next = patrolchannels;
  patrolchannels = pc;

  pc_check();

  return 0;
}
Ejemplo n.º 3
0
/**
 * handle the MKICK command
 */
void cs_mkick(char *src, int ac, char **av) {
	if (ac < 2) {
		notice(cs_name, src, CS_MKICK_ERR_USAGE);
		notice(cs_name, src, CS_RPL_HLP, cs_name, "MKICK");
		return;
	}
	char *chan = sstrdup(av[1]);
	char *reason = sstrdup(av[2]);
	user *u = finduser(src);
	if (!isregcs(chan)) {
		notice(cs_name, src, CS_ERR_NOTREG, chan);
		return;
	}
	ChanInfo *c = findchan(chan);
	if (cs_xop_get_level(u, c) < cs_mkick_access) {
		notice(cs_name, src, CS_XOP_ERR_HIGHERACCESS, get_opacc(cs_mkick_access));
		return;
	}
	channel *channel = findchannel(chan);
	int relevant_count;
	if(channel->bot) {
		relevant_count = 1;
	} else {
		relevant_count = 0;
	}
		if(channel->ucnt<relevant_count) {
		notice(cs_name,src,CS_MKICK_RPL_NOUSERS,chan);
		return;
	}
	char final_reason[256];
	sprintf(final_reason,"MKICK Command used by %s (%s)",src,reason);
	do_mkick(channel,final_reason);

	return;
}
Ejemplo n.º 4
0
int ca_carrot(void *source, int cargc, char **cargv) {
  nick *sender=(nick *)source;
  nick *victim;
  channel *cp;
  
  if (cargc<1)
    return CMD_USAGE;
  
  if ((victim=getnickbynick(cargv[0]))!=NULL) {
    controlreply(victim,"%cACTION ger %s en morot%c",1,victim->nick,1);
    controlreply(sender,"Gave %s a carrot.",victim->nick); 
  } else if ((cp=findchannel(cargv[0]))!=NULL) {
    if (cargc>1) {
      controlchanmsg(cp,"%cACTION ger %s en morot%c",1,cargv[1],1);
    } else {
      controlchanmsg(cp,"%cACTION waves a carrot around menacingly.%c",1,1);
    }
    
    controlreply(sender,"Used carrot in %s.",cp->index->name->content);
  } else {
    controlreply(sender,"Couldn't find %s.",cargv[0]);
  }
  
  return CMD_OK;
}
Ejemplo n.º 5
0
int handlepartmsg(void *source, int cargc, char **cargv) {
  char *pos,*nextchan;
  nick *np;
  channel *cp;
  void *harg[3];
  
  if (cargc<1) {
    return CMD_OK;
  }
 
  if (cargc>2) {
    Error("channel",ERR_WARNING,"PART with too many parameters (%d)",cargc);
  }
  
  if (cargc>1) {
    harg[2]=(void *)cargv[1];
  } else {
    harg[2]=(void *)"";
  }
  
  /* Find out who we are talking about here */
  np=getnickbynumericstr(source);
  if (np==NULL) {
    Error("channel",ERR_WARNING,"PART from non existent numeric %s",(char *)source);
    return CMD_OK;  
  }
  
  harg[1]=np;
  
  nextchan=pos=cargv[0];
  while (*nextchan!='\0') {
    /* Find the next chan position */
    for (;*pos!='\0' && *pos!=',';pos++)
      ; /* Empty loop */
  
    if (*pos==',') {
      *pos='\0';
      pos++;
    }
    
    /* OK, pos now points at either null or the next chan 
     * and nextchan now points at the channel name we want to parse next */
     
    if ((cp=findchannel(nextchan))==NULL) {
      /* Erm, parting a channel that's not there?? */
      Error("channel",ERR_WARNING,"Nick %s left non-existent channel %s",np->nick,nextchan);
    } else {
      /* Skip ghost parts (confirmation for kick from target server). */
      if (getnumerichandlefromchanhash(cp->users, np->numeric)) {
        /* Trigger hook *FIRST* */
        harg[0]=cp;
        triggerhook(HOOK_CHANNEL_PART,harg);
        delnickfromchannel(cp,np->numeric,1);
      }
    }
    nextchan=pos;
  }

  return CMD_OK;
}
Ejemplo n.º 6
0
void dbl_display(variable* ch, int count, ...)
{
	Channel* canal=findchannel(decimal2integer(ch));
	va_list arg;
	int i;
	variable* field;
	FILE* fh;

	if (canal->terminal==1)
		fh=stdout;
	else
		fh=canal->fh;

	va_start(arg,count);

	for (i = 0; i < count; i++) {
		field=va_arg(arg,variable*);
		if (gettype(field)<=tALPHA)
			fwrite(getdata(field),getsize(field),1,fh);
		if (gettype(field)==tDECIMAL) {
			int64 code;
			code=decimal2integer(field);
			code%=256;
			fprintf(fh,"%c",code);
		}
	}

	fflush(fh);

	va_end(arg);
}
Ejemplo n.º 7
0
	void Run(CommandSource &source, const Flux::vector &params)
	{
		Flux::string chan = params[1];
		User *u = source.u;

		if(!u->IsOwner())
		{
			source.Reply(ACCESS_DENIED);
			Log(u) << "attempted to make bot part " << chan;
			return;
		}

		if(!IsValidChannel(chan))
			source.Reply(CHANNEL_X_INVALID, chan.c_str());
		else
		{
			Channel *c = findchannel(chan);

			if(c)
				c->SendPart();
			else
				source.Reply("I am not in channel \2%s\2", chan.c_str());

			Log(u) << "made the bot part " << chan;
		}
	}
Ejemplo n.º 8
0
void spawnclones(unsigned int count) {
  nick *np;
  unsigned int i,j;
  char nick[11], ident[11], host[40];
  channel *cp;
  
  for (i=0;i<count;i++) {
    if (nclones >= MAXCLONES)
      return;
      
    for (j=0;j<10;j++) {
      nick[j]=(rand()%26)+'a';
      ident[j]=(rand()%26)+'a';
      host[j]=(rand()%26)+'a';
      host[j+11]=(rand()%26)+'a';
      host[j+22]=(rand()%26)+'a';
    }
    
    host[10]=host[21]='.';
    host[32]=nick[10]=ident[10]='\0';
    
    np=clones[nclones++]=registerlocaluser(nick, ident, host, host, "", 0, clonehandler);
    
    if ((cp=findchannel(HOMECHANNEL))) {
      localjoinchannel(np, cp);
    }
  }
}
Ejemplo n.º 9
0
int handletopicmsg(void *source, int cargc, char **cargv) {
  channel *cp;
  nick *np;
  void *harg[2];
  time_t topictime=0, timestamp=0;
  
  if (cargc<2) {
    return CMD_OK;
  }
  
  if (cargc>2)
    topictime=strtol(cargv[cargc-2], NULL, 10);
  
  if (cargc>3)
    timestamp=strtol(cargv[cargc-3], NULL, 10);
  
  np=getnickbynumericstr((char *)source);

  /* The following check removed because servers can set topics.. */
#if 0
  if (np==NULL) {
    /* We should check the sender exists, but we still change the topic even if it doesn't */
    Error("channel",ERR_WARNING,"Topic change by non-existent user %s",(char *)source);
  }
#endif
  
  /* Grab channel pointer */
  if ((cp=findchannel(cargv[0]))==NULL) {
    /* We're not going to create a channel for the sake of a topic.. */
    return CMD_OK;
  } else {
    if (timestamp && (cp->timestamp < timestamp)) {
      /* Ignore topic change for younger channel 
       * (note that topic change for OLDER channel should be impossible!) */
      return CMD_OK;
    }
    if (topictime && (cp->topictime > topictime)) {
      /* Ignore topic change with older topic */
      return CMD_OK;
    }
    if (cp->topic!=NULL) {
      freesstring(cp->topic);
    }
    if (cargv[cargc-1][0]=='\0') {
      cp->topic=NULL;
      cp->topictime=0;
    } else {
      cp->topic=getsstring(cargv[cargc-1],TOPICLEN);
      cp->topictime=topictime?topictime:getnettime();
    }
    /* Trigger hook */
    harg[0]=cp;
    harg[1]=np;
    triggerhook(HOOK_CHANNEL_TOPIC,harg);
  }
  
  return CMD_OK;
}
Ejemplo n.º 10
0
void makenick(void *arg) {
  channel *cp;
  
  cmnick=registerlocaluser(NICK, "clone", "master", "Clone Master", "", 0, masterhandler);
  
  if ((cp=findchannel(HOMECHANNEL))) {
    localjoinchannel(cmnick, cp);
  } else {
    localcreatechannel(cmnick, HOMECHANNEL);
  }
}
Ejemplo n.º 11
0
void join(char *chan) {
  channel *cp;
  unsigned int i;
  
  if (!(cp=findchannel(chan)))
    return;
  
  for(i=0;i<nclones;i++) {
    localjoinchannel(clones[i], cp);
  }
}
Ejemplo n.º 12
0
void dbl_delete(variable *ch, variable *keyfld)
{
	Channel *canal = findchannel(decimal2integer(ch));
	if (canal->submode == INDEXED) {
		/* You can note that keyfld is useless */
		char* query;
		asprintf(&query,"DELETE FROM %s WHERE id=%d",canal->filespec,canal->lastid);
		mysql_query(dibol->dbh,query);
		free(query);
	}
}
Ejemplo n.º 13
0
	EventResult OnLog(Log *l)
	{
		Channel *c = findchannel(Config->LogChan);

		if(!c)
			return EVENT_CONTINUE;

		std::stringstream logstream;
		Flux::string message = Flux::Sanitize(l->buffer.str());

		if(l->u && !l->c)
			message = l->u->nick + " " + message;

		if(l->u && l->c)
			message = l->u->nick + " used " + l->c->name + " " + message;

		switch(l->type)
		{
			case LOG_NORMAL:
				logstream << message;
				break;
			case LOG_THREAD:

				if(protocoldebug)
					logstream << "[THREAD] " << message;

				break;
			case LOG_DEBUG:

				if(dev || protocoldebug)
					logstream << message;

				break;
//       case LOG_DEVEL:
//  if(!protocoldebug && dev)
//    logstream << message;
//  break;
			case LOG_RAWIO:
				return EVENT_CONTINUE;
			case LOG_CRITICAL:
				logstream << "\0034[CRITICAL] " << message << "\017";
				break;
			case LOG_WARN:
				logstream << "\0037[WARNING]\017 " << message;
				break;
			default:
				break;
		}

		c->SendMessage(NoTermColor(logstream.str()));
		return EVENT_CONTINUE;
	}
Ejemplo n.º 14
0
void versionscan_createfakeuser(void* arg) {
  channel* cp;
  char buf[200];
  
  vsconnect=NULL;
  sprintf(buf, "%s v%s", VS_RNDESC, VS_VERSION);
  versionscan_nick=registerlocaluser(VS_NICK, VS_IDENT, VS_HOST, buf, VS_AUTHNAME, UMODE_ACCOUNT | UMODE_DEAF | UMODE_OPER | UMODE_SERVICE, versionscan_handler);
  if ((cp=findchannel(OPER_CHAN))) {
    localjoinchannel(versionscan_nick, cp);
    localgetops(versionscan_nick, cp);
  } else {
    localcreatechannel(versionscan_nick, OPER_CHAN);
  }
}
Ejemplo n.º 15
0
int handlekickmsg(void *source, int cargc, char **cargv) {
  nick *np,*kicker;
  channel *cp;
  void *harg[4];
  
  if (cargc<3) {
    return CMD_OK;
  }
  
  /* Find out who we are talking about here */
  if ((np=getnickbynumericstr(cargv[1]))==NULL) {
    Error("channel",ERR_DEBUG,"Non-existant numeric %s kicked from channel %s",(char *)source,cargv[0]);
    return CMD_OK;  
  }

  /* And who did the kicking */
  if (((char *)source)[2]=='\0') {
    /* 'Twas a server.. */
    kicker=NULL;
  } else if ((kicker=getnickbynumericstr((char *)source))==NULL) {
    /* It looks strange, but we let the kick go through anyway */
    Error("channel",ERR_DEBUG,"Kick from non-existant nick %s",(char *)source);
  }
  
  /* And find out which channel */
  if ((cp=findchannel(cargv[0]))==NULL) {
    /* OK, not a channel that actually exists then.. */
    Error("channel",ERR_DEBUG,"Nick %s kicked from non-existent channel %s",np->nick,cargv[0]);
  } else {
    /* Before we do anything else, we have to acknowledge the kick to the network */
    if (homeserver(np->numeric)==mylongnum) {
      irc_send("%s L %s",longtonumeric(np->numeric,5),cp->index->name->content);
    }

    /* Trigger hook *FIRST* */
    harg[0]=cp;
    harg[1]=np;
    harg[2]=kicker;
    harg[3]=cargv[2];
    triggerhook(HOOK_CHANNEL_KICK,harg);

    /* We let delnickfromchannel() worry about whether this nick is actually on this channel */
    delnickfromchannel(cp,np->numeric,1);  
  }
  
  return CMD_OK;
}
Ejemplo n.º 16
0
void dbl_writes (variable* ch, variable* record)
{
	Channel* canal=findchannel(decimal2integer(ch));
	if (canal==NULL) error(11);
	if (canal->terminal==1) {
		fwrite(getdata(record),getsize(record),1,stdout);
		printf("\n");	
		return;
	}
	if (canal->submode == SEQUENTIAL) {
		fwrite(getdata(record),getsize(record),1,canal->fh);
		fprintf(canal->fh,"\n");
		return;
	}
	if (canal->submode == RELATIVE ) {
		int seqnum;
		char *query;
		MYSQL_RES *result;
		MYSQL_ROW row;
		char *data = alpha2char (record);
		/* Compute the next free id */
		/* We iterate through the id while we found a free place */
		seqnum=(canal->lastid)+1;
		asprintf(&query,"SELECT id FROM %s WHERE id>%d ORDER BY id",canal->filespec,canal->lastid);
		mysql_query(dibol->dbh,query);
		free(query);
		result=mysql_use_result(dibol->dbh);
		while ( (row=mysql_fetch_row(result))) {
			if (seqnum!=strtol(row[0],NULL,10))
				break;
			seqnum++;
		}
		mysql_free_result(result);

		/* write the record */
		asprintf(&query,"INSERT INTO %s (id,data) VALUES (%d,\"%s\")",canal->filespec,seqnum,data);
		mysql_query(dibol->dbh,query);
		free(query);
		free(data);
		
		canal->lastid=seqnum;

		return;
	}
}
Ejemplo n.º 17
0
int versionscan_scan(void* sender, int cargc, char** cargv) {
  nick* np=(nick*)sender;
  nick* n;
  channel* cp;
  
  if (cargc < 1) {
    sendnoticetouser(versionscan_nick, np, "Syntax: scan <target>");
    return CMD_ERROR;
  }
  
  if (versionscan_mode != VS_SCAN) {
    sendnoticetouser(versionscan_nick, np, "Scanning of users is currently disabled.");
    return CMD_ERROR;
  }
  
  if (cargv[0][0] == '#') {
    if ((cp=findchannel(cargv[0]))) {
      sendmessagetochannel(versionscan_nick, cp, "\001VERSION\001");
      sendnoticetouser(versionscan_nick, np, "Done.");
    }
    else {
      sendnoticetouser(versionscan_nick, np, "No such channel.");
      return CMD_ERROR;
    }
  }
  else {
    if ((n=getnickbynick(cargv[0]))) {
      if (IsOper(n)) {
        sendnoticetouser(versionscan_nick, np, "Cannot scan IRC Operators.");
        return CMD_ERROR;
      }
      sendmessagetouser(versionscan_nick, n, "\001VERSION\001");
      sendnoticetouser(versionscan_nick, np, "Done.");
    }
    else {
      sendnoticetouser(versionscan_nick, np, "No such nick.");
      return CMD_ERROR;
    }
  }
  return CMD_OK;
}
Ejemplo n.º 18
0
static void pc_check(void) {
  patrolchannel *pc;
  channel *cp;

  for (pc = patrolchannels; pc; pc = pc->next) {
    if (pc->nick && pc->nick->timestamp > getnettime() - 900)
      continue;

    if (pc->nick)
      deregisterlocaluser(pc->nick, NULL);

    cp = findchannel(pc->channel->content);

    if (!cp) {
      pc->nick = NULL;
      continue;
    }

    pc->nick = patrol_generateclone(0, patroluserhandler);
    localjoinchannel(pc->nick, cp);
  }
}
Ejemplo n.º 19
0
	void Run(CommandSource &source, const Flux::vector &params)
	{
		User *u = source.u;
		Flux::string chan = params[1];

		if(!u->IsOwner())
		{
			source.Reply(ACCESS_DENIED);
			Log(u) << "attempted to make the bot join " << chan;
			return;
		}

		if(!IsValidChannel(chan))
			source.Reply(CHANNEL_X_INVALID, chan.c_str());
		else
		{
			Log(u) << "made the bot join " << chan;
			Channel *c = findchannel(chan);

			if(!c)
			{
				ircproto->join(chan);

				Flux::string WelcomeMessage = Config->WelcomeMessage.replace_all_ci("{botnick}", Config->BotNick);
				WelcomeMessage.trim();

				if(!WelcomeMessage.empty())
					ircproto->privmsg(chan, WelcomeMessage);
			}
			else
			{
				Log(u) << "tried to make bot join " << c->name << " but we're already in that channel";
				source.Reply("Already in \2%s\2", c->name.c_str());
			}
		}
	}
Ejemplo n.º 20
0
hchannel *hchannel_add(const char *cname)
{
    channel *cp;
    hchannel *hchan;

    cp = findchannel((char*)cname);
    if (!cp)
    {
        localcreatechannel(helpmodnick, (char*)cname);
        cp = findchannel((char*)cname);
    }
    else
    {
        localjoinchannel(helpmodnick, cp);
        localgetops(helpmodnick, cp);
    }

    hchan = (hchannel*)malloc(sizeof(hchannel));

    hchan->welcome[0] = '\0';
    hchan->real_channel = cp;
    hchan->flags = H_CHANFLAGS_DEFAULT;
    hchan->channel_users = NULL;
    hchan->channel_hterms = NULL;
    hchan->max_idle = 5 * HDEF_m;
    hchan->topic = NULL;
    hchan->report_to = NULL;

    hchan->autoqueue = 0;
    hchan->jf_control = time(NULL);
    hchan->lc_profile = NULL;
    hchan->censor = NULL;

    hchan->htickets = NULL;
    hchan->ticket_message = NULL;

    hchan->last_activity = time(NULL);
    hchan->last_staff_activity = time(NULL);
    hchan->stats = get_hstat_channel();

    hchan->next = hchannels;
    hchannels = hchan;

    {
        int i;
        nick *nck;
        huser *husr;
        huser_channel *tmp;
        for (i=0;i < hchan->real_channel->users->hashsize;i++)
        {
            nck = getnickbynumeric(hchan->real_channel->users->content[i]);
            if (!nck) /* it's a hash, not an array */
                continue;

            if ((husr = huser_get(nck)) == NULL)
                husr = huser_add(nck);

	    tmp = huser_add_channel(husr, hchan);
            hchannel_add_user(hchan, husr);

            if (hchan->real_channel->users->content[i] & CUMODE_OP)
                tmp->flags |= HCUMODE_OP;
            if (hchan->real_channel->users->content[i] & CUMODE_VOICE)
                tmp->flags |= HCUMODE_VOICE;
        }
    }
    return hchan;
}
Ejemplo n.º 21
0
int handlejoinmsg(void *source, int cargc, char **cargv) {
  char *pos,*nextchan;
  nick *np;
  void *harg[3];
  channel *cp,**ch;
  long timestamp=0;
  int i;
  int newchan=0;
  
  if (cargc<1) {
    return CMD_OK;
  }
  
  if (cargc>1) {
    /* We must have received a timestamp too */
    timestamp=strtol(cargv[1],NULL,10);
  }
  
  /* Find out who we are talking about here */
  np=getnickbynumericstr(source);
  if (np==NULL) {
    Error("channel",ERR_WARNING,"Channel join from non existent user %s",(char *)source);
    return CMD_OK;  
  }
  
  nextchan=pos=cargv[0];
  while (*nextchan!='\0') {
    /* Find the next chan position */
    for (;*pos!='\0' && *pos!=',';pos++)
      ; /* Empty loop */
  
    if (*pos==',') {
      *pos='\0';
      pos++;
    }
    
    /* OK, pos now points at either null or the next chan 
     * and nextchan now points at the channel name we want to parse next */
     
    if(nextchan[0]=='0' && nextchan[1]=='\0') {
      /* Leave all channels
       * We do this as if they were leaving the network, 
       * then vape their channels array and start again */
      ch=(channel **)(np->channels->content);
      for(i=0;i<np->channels->cursi;i++) {
        /* Send hook */
        harg[0]=ch[i];
        harg[1]=np;
        harg[2]=NULL;
        triggerhook(HOOK_CHANNEL_PART,harg);
        delnickfromchannel(ch[i],np->numeric,0);
      }
      array_free(np->channels);
      array_init(np->channels,sizeof(channel *));
    } else {
      /* It's an actual channel join */
      newchan=0;
      if ((cp=findchannel(nextchan))==NULL) {
        /* User joined non-existent channel - create it.  Note that createchannel automatically 
         * puts the right magic timestamp in for us */
        Error("channel",ERR_DEBUG,"User %s joined non existent channel %s.",np->nick,nextchan);
        cp=createchannel(nextchan);
        newchan=1;
      }
      if (cp->timestamp==MAGIC_REMOTE_JOIN_TS && timestamp) {
        /* No valid timestamp on the chan and we received one -- set */
        cp->timestamp=timestamp;
      }
      /* OK, this is slightly inefficient since we turn the nick * into a numeric,
       * and addnicktochannel then converts it back again.  BUT it's fewer lines of code :) */
      if (addnicktochannel(cp,np->numeric)) {
        /* The user wasn't added */
        if (newchan) {
          delchannel(cp);
        } 
      } else {
        chanindex *cip=cp->index;
         
        /* If we just created a channel, flag it */
        if (newchan) {
          triggerhook(HOOK_CHANNEL_NEWCHANNEL,cp);
        }
        
        /* Don't send HOOK_CHANNEL_JOIN if the channel doesn't exist any
         * more (can happen if something destroys it in response to
         * HOOK_CHANNEL_NEWCHANNEL) */
        if (cp == cip->channel) {
          /* send hook */
          harg[0]=cp;
          harg[1]=np;
          triggerhook(HOOK_CHANNEL_JOIN,harg);
        }
      }
    }
    nextchan=pos;
  }
  return CMD_OK;
}
Ejemplo n.º 22
0
int handleclearmodemsg(void *source, int cargc, char **cargv) {
  channel *cp;
  void *harg[4];
  nick *np, *target;
  char *mcp;
  unsigned long usermask=0;
  int i;
  int changes=0;

  if (cargc<2) {
    return CMD_OK;
  }

  if ((cp=findchannel(cargv[0]))==NULL) {
    /* No channel, abort */
    Error("channel",ERR_WARNING,"Mode change on non-existent channel %s",cargv[0]);
    return CMD_OK;
  }

  if (((char *)source)[2]=='\0') {
    /* Server mode change? (I don't think servers are allowed to do CLEARMODE) */
    np=NULL;
  } else if ((np=getnickbynumericstr((char *)source))==NULL) {
    /* No sender, continue but moan */
    Error("channel",ERR_WARNING,"Mode change by non-existent user %s on channel %s",(char *)source,cp->index->name->content);
  }
             
  harg[0]=cp;
  harg[1]=np;
  harg[3]=(void *)(long)(cp->flags);

  for (mcp=cargv[1];*mcp;mcp++) {
    switch (*mcp) {
      case 'o':
        usermask |= CUMODE_OP;
	changes |= MODECHANGE_USERS;
        break;
      
      case 'v':
        usermask |= CUMODE_VOICE;
	changes |= MODECHANGE_USERS;
        break;
        
      case 'n':
        ClearNoExtMsg(cp);
	changes |= MODECHANGE_MODES;
        break;
        
      case 't':
        ClearTopicLimit(cp);
	changes |= MODECHANGE_MODES;
        break;
      
      case 's':
        ClearSecret(cp);
	changes |= MODECHANGE_MODES;
        break;
        
      case 'p':
        ClearPrivate(cp);
	changes |= MODECHANGE_MODES;
        break;
        
      case 'i':
        ClearInviteOnly(cp);
	changes |= MODECHANGE_MODES;
        break;
        
      case 'm':
        ClearModerated(cp);
	changes |= MODECHANGE_MODES;
        break;
        
      case 'c':
        ClearNoColour(cp);
	changes |= MODECHANGE_MODES;
        break;
        
      case 'C':
        ClearNoCTCP(cp);
	changes |= MODECHANGE_MODES;
        break;
        
      case 'r':
        ClearRegOnly(cp);
	changes |= MODECHANGE_MODES;
        break;
      
      case 'D':
        ClearDelJoins(cp);
	changes |= MODECHANGE_MODES;
        break;

      case 'u':
        ClearNoQuitMsg(cp);
        changes |= MODECHANGE_MODES;
	break;

      case 'N':
        ClearNoNotice(cp);
        changes |= MODECHANGE_MODES;
        break;
        
      case 'M':
        ClearModNoAuth(cp);
        changes |= MODECHANGE_MODES;
        break;
      
      case 'T':
        ClearSingleTarg(cp);
        changes |= MODECHANGE_MODES;
        break;

      case 'b':
        clearallbans(cp);
	changes |= MODECHANGE_BANS;
	break;
        
      case 'k':
        /* This is all safe even if there is no key atm */
        freesstring(cp->key);
        cp->key=NULL;
        ClearKey(cp);
	changes |= MODECHANGE_MODES;
        break;
        
      case 'l':
        cp->limit=0;
        ClearLimit(cp);
	changes |= MODECHANGE_MODES;
        break;
    }
  }
   
  if (usermask) {
    /* We have to strip something off each user */
    for (i=0;i<cp->users->hashsize;i++) {
      if (cp->users->content[i]!=nouser && (cp->users->content[i] & usermask)) {
        /* This user exists and has at least one of the modes we're clearing */
        if ((target=getnickbynumeric(cp->users->content[i]))==NULL) {
          /* This really is a fuckup, we found them on the channel but there isn't a user with that numeric */
          /* This means there's a serious bug in the nick/channel tracking code */
          Error("channel",ERR_ERROR,"CLEARMODE failed: user on channel who doesn't exist?");
        } else {
          harg[2]=target;                                  
          /* Yes, these are deliberate three way bitwise ANDs.. */
          if (cp->users->content[i] & usermask & CUMODE_OP)
            triggerhook(HOOK_CHANNEL_DEOPPED, harg);
          if (cp->users->content[i] & usermask & CUMODE_VOICE)
            triggerhook(HOOK_CHANNEL_DEVOICED, harg);          
          cp->users->content[i] &= ~usermask;
        }
      }
    }
  }

  harg[2]=(void *)((long)changes);
  triggerhook(HOOK_CHANNEL_MODECHANGE, harg);
  return CMD_OK;
}
Ejemplo n.º 23
0
int handlecreatemsg(void *source, int cargc, char **cargv) {
  char *pos,*nextchan;
  nick *np;
  channel *cp;
  long timestamp=0;
  int newchan=1;
  void *harg[2];
  
  if (cargc<2) {
    return CMD_OK;
  }
  
  timestamp=strtol(cargv[1],NULL,10);
  
  /* Find out who we are talking about here */
  np=getnickbynumericstr(source);
  if (np==NULL) {
    Error("channel",ERR_WARNING,"Channel create from non existent user %s",(char *)source);
    return CMD_OK;  
  }
  
  nextchan=pos=cargv[0];
  while (*nextchan!='\0') {
    /* Find the next chan position */
    for (;*pos!='\0' && *pos!=',';pos++)
      ; /* Empty loop */
  
    if (*pos==',') {
      *pos='\0';
      pos++;
    }
    
    /* OK, pos now points at either null or the next chan 
     * and nextchan now points at the channel name we want to parse next */
     
    /* It's a channel create */
    if ((cp=findchannel(nextchan))==NULL) {
      /* This is the expected case -- the channel didn't exist before */
      cp=createchannel(nextchan);
      cp->timestamp=timestamp;
      newchan=1;
    } else {
      Error("channel",ERR_DEBUG,"Received CREATE for already existing channel %s",cp->index->name->content);
      if (cp->timestamp==MAGIC_REMOTE_JOIN_TS && timestamp) {
        /* No valid timestamp on the chan and we received one -- set */
        cp->timestamp=timestamp;
      }
      newchan=0;
    }
    /* Add the user to the channel, preopped */
    if (addnicktochannel(cp,(np->numeric)|CUMODE_OP)) {
      if (newchan) {
        delchannel(cp);
      }
    } else {
      chanindex *cip = cp->index;
        
      /* Flag the channel as new if necessary */
      if (newchan) {
        triggerhook(HOOK_CHANNEL_NEWCHANNEL,cp);
      }
    
      /* If HOOK_CHANNEL_NEWCHANNEL has caused the channel to be deleted,
       * don't trigger the CREATE hook. */
      if (cip->channel == cp) {
        /* Trigger hook */
        harg[0]=cp;
        harg[1]=np;
        triggerhook(HOOK_CHANNEL_CREATE,harg);
      }
    }
    nextchan=pos;
  }

  return CMD_OK;
}
Ejemplo n.º 24
0
int handleburstmsg(void *source, int cargc, char **cargv) {
  channel *cp;
  time_t timestamp;
  int wipeout=0;
  int i;
  int arg=0;
  char *charp;
  int newlimit;
  int waslimit,waskeyed;
  char *nextnum;
  unsigned long currentmode;
  int isnewchan;
  
  /* (we don't see the first 2 params in cargc) */
  /* AK B #+lod+ 1017561154 +tnk eits ATJWu:o,AiW1a,Ag3lV,AiWnl,AE6oI :%*[email protected] */
  
  if (cargc<2) {
    Error("channel",ERR_WARNING,"Burst message with only %d parameters",cargc);
    return CMD_OK;
  }
  
  timestamp=strtol(cargv[1],NULL,10);
  
  if ((cp=findchannel(cargv[0]))==NULL) {
    /* We don't have this channel already */
    cp=createchannel(cargv[0]);
    cp->timestamp=timestamp;
    isnewchan=1;
  } else {
    isnewchan=0;
    if (timestamp<cp->timestamp) {
      /* The incoming timestamp is older.  Erase all our current channel modes, and the topic. */
      cp->timestamp=timestamp;
      freesstring(cp->topic);
      cp->topic=NULL;
      cp->topictime=0;
      freesstring(cp->key);
      cp->key=NULL;
      cp->limit=0;
      cp->flags=0;
      clearallbans(cp);
      /* Remove all +v, +o we currently have */
      for(i=0;i<cp->users->hashsize;i++) {
        if (cp->users->content[i]!=nouser) {
          cp->users->content[i]&=CU_NUMERICMASK;
        }
      }
    } else if (timestamp>cp->timestamp) {
      /* The incoming timestamp is greater.  Ignore any incoming modes they may happen to set */
      wipeout=1;
    }
  }

  /* OK, dealt with the name and timestamp. 
   * Loop over the remaining args */
  for (arg=2;arg<cargc;arg++) {
    if (cargv[arg][0]=='+') {
      /* Channel modes */
      if (wipeout) {
        /* We ignore the modes, but we need to see if they include +l or +k 
         * so that we can ignore their corresponding values */
        for (charp=cargv[arg];*charp;charp++) {
          if (*charp=='k' || *charp=='l') {
            arg++;
          }
        }
      } else {
        /* Clear off the limit and key flags before calling setflags so we can see if the burst tried to set them */
        /* If the burst doesn't set them, we restore them afterwards */
        waslimit=IsLimit(cp); ClearLimit(cp);
        waskeyed=IsKey(cp);   ClearKey(cp);
        /* We can then use the flag function for these modes */
        setflags(&(cp->flags),CHANMODE_ALL,cargv[arg],cmodeflags,REJECT_NONE);
        /* Pick up the limit and key, if they were set.  Note that the limit comes first */
        if (IsLimit(cp)) { /* A limit was SET by the burst */
          if (++arg>=cargc) {
            /* Ran out of args -- damn ircd is spewing out crap again */
            Error("channel",ERR_WARNING,"Burst +l with no argument");
            break; /* "break" being the operative word */
          } else {
            newlimit=strtol(cargv[arg],NULL,10);
          }
          if (cp->limit>0 && waslimit) {
            /* We had a limit before -- we now have the lowest one of the two */
            if (newlimit<cp->limit) {
              cp->limit=newlimit;
            }
          } else {
            /* No limit before -- we just have the new one */
            cp->limit=newlimit;
          }
        } else if (waslimit) {
          SetLimit(cp); /* We had a limit before, but the burst didn't set one.  Restore flag. */
        }
        
        if (IsKey(cp)) { /* A key was SET by the burst */
          if (++arg>=cargc) {
            /* Ran out of args -- oopsie! */
            Error("channel",ERR_WARNING,"Burst +k with no argument");
            break;
          }
          if (waskeyed) {
            /* We had a key before -- alphabetically first wins */
            if (ircd_strcmp(cargv[arg],cp->key->content)<0) {
              /* Replace our key */
              freesstring(cp->key);
              cp->key=getsstring(cargv[arg],KEYLEN);
            }
          } else {
            /* No key before -- just the new one */
            cp->key=getsstring(cargv[arg],KEYLEN);
          }
        } else if (waskeyed) {
          SetKey(cp); /* We had a key before, but the burst didn't set one.  Restore flag. */
        }
      }       
    } else if (cargv[arg][0]=='%') {
      /* We have one or more bans here */
      nextnum=cargv[arg]+1;
      while (*nextnum) {
        /* Split off the next ban */
        for (charp=nextnum;*charp;charp++) {
          if (*charp==' ') {
            *charp='\0';
            charp++;
            break;
          }
        }        
        setban(cp,nextnum);
        nextnum=charp;
      }
    } else {
      /* List of numerics */
      nextnum=charp=cargv[arg];
      currentmode=0;
      while (*nextnum!='\0') {
        /* Step over the next numeric */
        for (i=0;i<5;i++) {
          if (*charp++=='\0')
            break;
        }
        if (i<5) {
          break;
        }
        if (*charp==',') {
          *charp='\0';
          charp++;
        } else if (*charp==':') {
          *charp='\0';
          charp++;
          currentmode=0;
          /* Look for modes */
          for (;*charp;charp++) {
            if (*charp=='v') {
              currentmode|=CUMODE_VOICE;
            } else if (*charp=='o') {
              currentmode|=CUMODE_OP;
            } else if (*charp==',') {
              charp++;
              break;
            }
          }
          /* If we're ignore incoming modes, zap it to zero again */
          if (wipeout) {
            currentmode=0;
          }
        }
        /* OK.  At this point charp points to either '\0' if we're at the end,
         * or the start of the next numeric otherwise.  nextnum points at a valid numeric
         * we need to add, and currentmode reflects the correct mode */
        addnicktochannel(cp,(numerictolong(nextnum,5)|currentmode));
        nextnum=charp;
      }
    }
  }
  if (cp->users->totalusers==0) {
    /* Oh dear, the channel is now empty.  Perhaps one of those 
     * charming empty burst messages you get sometimes.. */
    if (!isnewchan) {
      /* I really don't think this can happen, can it..? */
      /* Only send the LOSTCHANNEL if the channel existed before */
      triggerhook(HOOK_CHANNEL_LOSTCHANNEL,cp);
    }
    delchannel(cp);
  } else {
    /* If this is a new channel, we do the NEWCHANNEL hook also */
    if (isnewchan) {
      triggerhook(HOOK_CHANNEL_NEWCHANNEL,cp);
    }
    /* Just one hook to say "something happened to this channel" */
    triggerhook(HOOK_CHANNEL_BURST,cp);       
  }
   
  return CMD_OK;     
}
Ejemplo n.º 25
0
int handlemodemsg(void *source, int cargc, char **cargv) {
  channel *cp;
  int dir=1;
  int arg=2;
  char *modestr;
  unsigned long *lp;
  void *harg[4];
  nick *np, *target;
  int hooknum;
  int changes=0;

  if (cargc<2) {
    return CMD_OK;
  }

  if (cargv[0][0]!='#' && cargv[0][0]!='+') {
    /* Not a channel, ignore */
    return CMD_OK;
  }

  if ((cp=findchannel(cargv[0]))==NULL) {
    /* No channel, abort */
    Error("channel",ERR_WARNING,"Mode change on non-existent channel %s",cargv[0]);
    return CMD_OK;
  }
  
  if (((char *)source)[2]=='\0') {
    /* Server mode change, treat as divine intervention */
    np=NULL;
  } else if ((np=getnickbynumericstr((char *)source))==NULL) {
    /* No sender, continue but moan */
    Error("channel",ERR_WARNING,"Mode change by non-existent user %s on channel %s",(char *)source,cp->index->name->content);
  }
  
  /* Set up the hook data */
  harg[0]=cp;
  harg[1]=np;
  harg[3]=(void *)(long)(cp->flags);
  
  /* Process the mode string one character at a time */
  /* Maybe I'll write this more intelligently one day if I can comprehend the ircu code that does this */
  for (modestr=cargv[1];*modestr;modestr++) {
    switch(*modestr) {
      /* Set whether we are adding or removing modes */
      
      case '+': 
        dir=1;
        break;
        
      case '-':
        dir=0;
        break;
      
      /* Simple modes: just set or clear based on value of dir */
      
      case 'n':
        if (dir) { SetNoExtMsg(cp); } else { ClearNoExtMsg(cp); }
	changes |= MODECHANGE_MODES;
        break;
      
      case 't':
        if (dir) { SetTopicLimit(cp); } else { ClearTopicLimit(cp); }
	changes |= MODECHANGE_MODES;
        break;
      
      case 's':
        if (dir) { SetSecret(cp); ClearPrivate(cp); } else { ClearSecret(cp); }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'p':
        if (dir) { SetPrivate(cp); ClearSecret(cp); } else { ClearPrivate(cp); }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'i':
        if (dir) { SetInviteOnly(cp); } else { ClearInviteOnly(cp); }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'm':
        if (dir) { SetModerated(cp); } else { ClearModerated(cp); }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'c':
        if (dir) { SetNoColour(cp); } else { ClearNoColour(cp); }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'C':
        if (dir) { SetNoCTCP(cp); } else { ClearNoCTCP(cp); }
	changes |= MODECHANGE_MODES;
        break;
      
      case 'r':
        if (dir) { SetRegOnly(cp); } else { ClearRegOnly(cp); }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'D':
        if (dir) { SetDelJoins(cp); } else { ClearDelJoins(cp); }
	changes |= MODECHANGE_MODES;
        break;

      case 'u':
        if (dir) { SetNoQuitMsg(cp); } else { ClearNoQuitMsg(cp); }
        changes |= MODECHANGE_MODES;
        break;
      
      case 'N':
        if (dir) { SetNoNotice(cp); } else { ClearNoNotice(cp); }
        changes |= MODECHANGE_MODES;
        break;
        
      case 'M':
        if (dir) { SetModNoAuth(cp); } else { ClearModNoAuth(cp); }
        changes |= MODECHANGE_MODES;
        break;
      
      case 'T':
        if (dir) { SetSingleTarg(cp); } else { ClearSingleTarg(cp); }
        changes |= MODECHANGE_MODES;
        break;
        
      /* Parameter modes: advance parameter and possibly read it in */    
    
      case 'l':
        if (dir) {
          /* +l uses a parameter, but -l does not.
           * If there is no parameter, don't set the mode.
           * I guess we should moan too in that case, but 
           * they might be even nastier to us if we do ;) */
          if (arg<cargc) {
            cp->limit=strtol(cargv[arg++],NULL,10);
            SetLimit(cp);
          }      
        } else {
          ClearLimit(cp);
          cp->limit=0;
        }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'k':
        if (dir) {
          /* +k uses a parameter in both directions */
          if (arg<cargc) {
            freesstring(cp->key); /* It's probably NULL, but be safe */
            cp->key=getsstring(cargv[arg++],KEYLEN);
            SetKey(cp);
          }
        } else {
          freesstring(cp->key);
          cp->key=NULL;
          ClearKey(cp);
          arg++; /* Eat the arg without looking at it, even if it's not there */
        }
	changes |= MODECHANGE_MODES;
        break;
        
      /* Op/Voice */
      
      case 'o':
      case 'v': 
        if (arg<cargc) {
          if((lp=getnumerichandlefromchanhash(cp->users,numerictolong(cargv[arg++],5)))==NULL) {
            /* They're not on the channel; MODE crossed with part/kill/kick/blah */
            Error("channel",ERR_DEBUG,"Mode change for user %s not on channel %s",cargv[arg-1],cp->index->name->content);
          } else { 
            if ((target=getnickbynumeric(*lp))==NULL) {
              /* This really is a fuckup, we found them on the channel but there isn't a user with that numeric */
              /* This means there's a serious bug in the nick/channel tracking code */
              Error("channel",ERR_ERROR,"Mode change for user %s on channel %s who doesn't exist",cargv[arg-1],cp->index->name->content);
            } else { /* Do the mode change whilst admiring the beautiful code layout */
              harg[2]=target;
              if (*modestr=='o') { if (dir) { *lp |= CUMODE_OP;     hooknum=HOOK_CHANNEL_OPPED;    } else 
                                            { *lp &= ~CUMODE_OP;    hooknum=HOOK_CHANNEL_DEOPPED;  } }
                            else { if (dir) { *lp |= CUMODE_VOICE;  hooknum=HOOK_CHANNEL_VOICED;   } else 
                                            { *lp &= ~CUMODE_VOICE; hooknum=HOOK_CHANNEL_DEVOICED; } } 
              triggerhook(hooknum,harg);
            }
          }
        }
	changes |= MODECHANGE_USERS;
        break;
        
      case 'b':
        if (arg<cargc) {
          if (dir) {
            setban(cp,cargv[arg++]);
            triggerhook(HOOK_CHANNEL_BANSET,harg);
          } else {
            clearban(cp,cargv[arg++],0);
            triggerhook(HOOK_CHANNEL_BANCLEAR,harg);
          }
        }
	changes |= MODECHANGE_BANS;
        break;
        
      default:
        Error("channel",ERR_DEBUG,"Unknown mode char '%c' %s on %s",*modestr,dir?"set":"cleared",cp->index->name->content);
        break;
    }
  }

  harg[2]=(void *)((long)changes);
  triggerhook(HOOK_CHANNEL_MODECHANGE,(void *)harg);  
  return CMD_OK;
}
Ejemplo n.º 26
0
int loadchandb(char *filename) {
    FILE *fp;
    channel *cp; /* Current channel will be here */
    char line[1024]; /* Large buffer, just incase */
    char *charp;
    int loaded = 0;

    if (!(fp = fopen(filename, "r"))) {
        printlog("Could not open channel file %s.", filename);
        return 0;
    }

    while((fgets(line, 1023, fp))) {
        /* Read out the line and skip any comments and empty lines too. */
        /* Valid comments are: # and // */
        if (line[0] == '#' || (line[0] == '/' && line[1] == '/') || line[0] == '\n' || line[0] == '\r')
            continue;

        /* Remove the end-of-line chars here */
        for (charp = line; *charp; charp++) {
            if (*charp == '\n' || *charp == '\r') {
                *charp = '\0';
                break;
            }
        }

        /* Is the line long enough? */
        /* It needs to be atleast 3 chars long */
        /* [#channel] or key=setting */
        if (strlen(line) < 3)
            continue;

        /* Find channelname or setting */
        if (line[0] == '[') {
            for (charp = &(line[1]); *charp; charp++) {
                if (*charp == ']') {
                    *charp = '\0';
                    break;
                }
            }
            if (!(cp = findchannel(&(line[1]))))
                cp = addchannel(&(line[1]));
            loaded++;
            continue;
        }

        /* Next line must be a setting */
        if (cp) {
            for (charp = line; *charp; charp++) {
                if (*charp == '=') {
                    *charp = '\0';

                    /* Make sure the setting isn't empty */
                    if (!strlen(charp + 1))
                      break;

                    /* Now check the input and assign accordingly */
                    if (!strcasecmp(line, "createdat")) {
                        cp->createdat = (time_t)atoll(charp + 1);
                    } else if (!strcasecmp(line, "lastjoin")) {
                        cp->lastjoin = (time_t)atoll(charp + 1);
                    } else if (!strcasecmp(line, "flags")) {
                        cp->flags = atoi(charp + 1);
                    }
                }
            }
        }
    }

    fclose(fp);

    return loaded;
}
Ejemplo n.º 27
0
int loaduserdb(char *filename) {
    FILE *fp;
    dbuser *dup;
    account *ap;
    channel *cp = NULL;
    chanlevel *clp = NULL;
    char line[1024]; /* Large buffer, just incase */
    char *charp;
    int loaded = 0;

    if (!(fp = fopen(filename, "r"))) {
        printlog("Could not open user file %s.", filename);
        return 0;
    }

    while((fgets(line, 1023, fp))) {
        /* Read out the line and skip any comments and empty lines too. */
        /* Valid comments are: # and // */
        if (line[0] == '#' || (line[0] == '/' && line[1] == '/') || line[0] == '\n' || line[0] == '\r')
            continue;

        /* Remove the end-of-line chars here */
        for (charp = line; *charp; charp++) {
            if (*charp == '\n' || *charp == '\r') {
                *charp = '\0';
                break;
            }
        }

        /* Is the line long enough? */
        /* It needs to be atleast 3 chars long */
        /* [#account] or <#channel> or key=setting */
        if (strlen(line) < 3)
            continue;

        /* Find accountname or setting */
        if (line[0] == '[') {
            for (charp = &(line[1]); *charp; charp++) {
                if (*charp == ']') {
                    *charp = '\0';
                    break;
                }
            }
            if (!(ap = findaccount(&(line[1]))))
                ap = addaccount(&(line[1]));
            
            printlog("added new account: %s", ap->name);

            dup = newdbuser();
            /* Link account with dbuser */
            ap->dbuser = dup;
            dup->account = ap;
            cp = NULL;
            clp = NULL;
            loaded++;
            continue;
        }

        /* Next line must be a setting */
        if (ap) {
            if (line[0] == '<') {
                for (charp = &(line[1]); *charp; charp++) {
                    if (*charp == '>') {
                        *charp = '\0';
                        break;
                    }
                }
                cp = findchannel(&(line[1]));
                if (cp)
                    clp = addchanlevel(cp, ap);
                continue;
             }
             
             for (charp = line; *charp; charp++) {
                 if (*charp == '=') {
                     *charp = '\0';

                     /* Make sure the setting isn't empty */
                     if (!strlen(charp + 1))
                         break;

                     /* Now check the input and assign accordingly */
                     if (cp && clp) {
                         /* This is a chanlevel entry */
                         if (!strcasecmp(line, "lastchanged")) {
                             clp->lastchanged = (time_t)atoll(charp + 1);
                         } else if (!strcasecmp(line, "lastseen")) {
                             clp->lastseen = (time_t)atoll(charp + 1);
                         } else if (!strcasecmp(line, "flags")) {
                             clp->flags = atoi(charp + 1);
                         }
                     } else {
                         /* This is a dbuser entry */
                         if (!strcasecmp(line, "flags")) {
                            ap->dbuser->flags = atoi(charp + 1);
                         } else if (!strcasecmp(line, "lastseen")) {
                             ap->dbuser->lastseen = (time_t)atoll(charp + 1);
                         } else if (!strcasecmp(line, "trigger")) {
                             ap->dbuser->trigger = atoi(charp + 1);
                         }
                     }
                }
            }
        }
    }

    fclose(fp);
    return loaded;
}