示例#1
0
文件: ctcp.c 项目: vap0r/wraith
static int ctcp_CHAT(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
{

  if (!ischanhub()) 
    return BIND_RET_LOG;

    if (u_pass_match(u, "-")) {
      strlcat(ctcp_reply, "\001ERROR no password set\001", sizeof(ctcp_reply));
      return BIND_RET_BREAK;
    }

    int ix = -1, i = 0;

    for (i = 0; i < dcc_total; i++) {
      if (dcc[i].type && (dcc[i].type->flags & DCT_LISTEN) && (!strcmp(dcc[i].nick, "(telnet)")))
        ix = i;
    }
    if (!iptolong(getmyip())) {
      simple_snprintf(&ctcp_reply[strlen(ctcp_reply)], sizeof(ctcp_reply) - strlen(ctcp_reply), "\001ERROR no ipv4 ip defined. Use /dcc chat %s\001", botname);
    } else if (dcc_total == max_dcc || (ix < 0 && (ix = listen_all(0, 0, 0)) < 0))
      strlcat(ctcp_reply, "\001ERROR no telnet port\001", sizeof(ctcp_reply));
    else {
      if (listen_time <= 2)
        listen_time++;
      /* do me a favour and don't change this back to a CTCP reply,
       * CTCP replies are NOTICE's this has to be a PRIVMSG
       * -poptix 5/1/1997 */
      bd::String msg;
      msg = bd::String::printf("\001DCC CHAT chat %lu %u\001", iptolong(getmyip()), dcc[ix].port);
      privmsg(nick, msg.c_str(), DP_SERVER);
    }
    return BIND_RET_BREAK;
}
示例#2
0
static void remote_filereq(int idx, char *from, char *file)
{
  char *p, what[256], dir[256], s[256], s1[256], *reject;
  FILE *f;
  filedb fdb;
  long i = 0;

  strcpy(what, file);
  p = strrchr(what, '/');
  if (p == NULL)
    dir[0] = 0;
  else {
    *p = 0;
    strcpy(dir, what);
    strcpy(what, p + 1);
  }
  f = filedb_open(dir, 0);
  reject = NULL;
  if (f == NULL) {
    reject = FILES_DIRDNE;
  } else {
    if (!findmatch(f, what, &i, &fdb)) {
      reject = FILES_FILEDNE;
      filedb_close(f);
    } else {
      if ((!(fdb.stat & FILE_SHARE)) ||
	  (fdb.stat & (FILE_HIDDEN | FILE_DIR))) {
	reject = FILES_NOSHARE;
	filedb_close(f);
      } else {
	filedb_close(f);
	/* copy to /tmp if needed */
	sprintf(s1, "%s%s%s%s", dccdir, dir, dir[0] ? "/" : "", what);
	if (copy_to_tmp) {
	  sprintf(s, "%s%s", tempdir, what);
	  copyfile(s1, s);
	} else
	  strcpy(s, s1);
	i = raw_dcc_send(s, "*remote", FILES_REMOTE, s);
	if (i > 0) {
	  wipe_tmp_filename(s, -1);
	  reject = FILES_SENDERR;
	}
      }
    }
  }
  simple_sprintf(s1, "%s:%s/%s", botnetnick, dir, what);
  if (reject) {
    botnet_send_filereject(idx, s1, from, reject);
    return;
  }
  /* grab info from dcc struct and bounce real request across net */
  i = dcc_total - 1;
  simple_sprintf(s, "%d %u %d", iptolong(getmyip()), dcc[i].port,
		dcc[i].u.xfer->length);
  botnet_send_filesend(idx, s1, from, s);
  putlog(LOG_FILES, "*", FILES_REMOTEREQ, dir, dir[0] ? "/" : "", what);
}
示例#3
0
文件: chanprog.c 项目: x90/wraith
void setup_HQ(int n) {
    dcc[n].addr = iptolong(getmyip());
    dcc[n].sock = STDOUT;
    dcc[n].timeval = now;
    dcc[n].u.chat->con_flags = conmask | LOG_ALL;
    dcc[n].u.chat->strip_flags = STRIP_ALL;
    dcc[n].status = STAT_ECHO;
    strlcpy(dcc[n].nick, STR("HQ"), sizeof(dcc[n].nick));
    strlcpy(dcc[n].host, STR("llama@console"), sizeof(dcc[n].host));
    dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
    /* Make sure there's an innocuous HQ user if needed */
    if (!dcc[n].user) {
      userlist = adduser(userlist, dcc[n].nick, "none", "-", USER_ADMIN | USER_OWNER | USER_MASTER | USER_VOICE | USER_OP | USER_PARTY | USER_CHUBA | USER_HUBA, 0);
      dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
    }
}
示例#4
0
static void remote_filereq(int idx, char *from, char *file)
{
    char *p = NULL, *what = NULL, *dir = NULL,
          *s1 = NULL, *reject = NULL, *s = NULL;
    FILE *fdb = NULL;
    int i = 0;
    filedb_entry *fdbe = NULL;

    malloc_strcpy(what, file);
    p = strrchr(what, '/');
    if (p) {
        *p = 0;
        malloc_strcpy(dir, what);
        strcpy(what, p + 1);
    } else {
        malloc_strcpy(dir, "");
    }
    fdb = filedb_open(dir, 0);
    if (!fdb) {
        reject = FILES_DIRDNE;
    } else {
        filedb_readtop(fdb, NULL);
        fdbe = filedb_matchfile(fdb, ftell(fdb), what);
        filedb_close(fdb);
        if (!fdbe) {
            reject = FILES_FILEDNE;
        } else {
            if ((!(fdbe->stat & FILE_SHARE)) ||
                    (fdbe->stat & (FILE_HIDDEN | FILE_DIR)))
                reject = FILES_NOSHARE;
            else {
                s1 = nmalloc(strlen(dccdir) + strlen(dir) + strlen(what) + 2);
                /* Copy to /tmp if needed */
                sprintf(s1, "%s%s%s%s", dccdir, dir, dir[0] ? "/" : "", what);
                if (copy_to_tmp) {
                    s = nmalloc(strlen(tempdir) + strlen(what) + 1);
                    sprintf(s, "%s%s", tempdir, what);
                    copyfile(s1, s);
                } else
                    s = s1;
                i = raw_dcc_send(s, "*remote", FILES_REMOTE, s);
                if (i > 0) {
                    wipe_tmp_filename(s, -1);
                    reject = FILES_SENDERR;
                }
                if (s1 != s)
                    my_free(s);
                my_free(s1);
            }
            free_fdbe(&fdbe);
        }
    }
    s1 = nmalloc(strlen(botnetnick) + strlen(dir) + strlen(what) + 3);
    simple_sprintf(s1, "%s:%s/%s", botnetnick, dir, what);
    if (reject) {
        botnet_send_filereject(idx, s1, from, reject);
        my_free(s1);
        my_free(what);
        my_free(dir);
        return;
    }
    /* Grab info from dcc struct and bounce real request across net */
    i = dcc_total - 1;
    s = nmalloc(40);              /* Enough? */
    simple_sprintf(s, "%d %u %d", iptolong(getmyip()), dcc[i].port,
                   dcc[i].u.xfer->length);
    botnet_send_filesend(idx, s1, from, s);
    putlog(LOG_FILES, "*", FILES_REMOTEREQ, dir, dir[0] ? "/" : "", what);
    my_free(s1);
    my_free(s);
    my_free(what);
    my_free(dir);
}
示例#5
0
int main(int argc, char** argv)
{
	int exitstatus = 0;


	/* declare CL args */
	arg_lit_t *help = (arg_lit_t*) arg_lit0("h", "help", "prints the command glossary");
	arg_lit_t *myip = (arg_lit_t*) arg_lit0("m", NULL, "prints the external ip of the interface currently being used");
	arg_lit_t *bounce_opt = (arg_lit_t*) arg_lit0("b", NULL, "creates a bouncer to send the message received back to the sender");
	arg_lit_t *listen_opt = (arg_lit_t*) arg_lit0("l", NULL, "creates a listener to print the messages received");
	
	arg_file_t *proto = (arg_file_t*) arg_filen("p", "protocol", "acronym", 0, 1, "specify the protocol being manipulated");
	arg_file_t *source = (arg_file_t*) arg_filen("s", "source", "x.x.x.x", 0, 1, "specify the source IP");
	arg_file_t *dest = (arg_file_t*) arg_filen("d", "dest", "x.x.x.x", 0, 1, "specify the destination IP");
	arg_int_t *sport = (arg_int_t*) arg_intn(NULL, "srcport", "short", 0, 1, "specify the source port if applicable");
	arg_int_t *dport = (arg_int_t*) arg_intn(NULL, "dstport", "short", 0, 1, "specify the destination port if applicable");

	arg_str_t *mcontent = (arg_str_t*) arg_strn(NULL, NULL, "string", 0, 1, "message content as a string");
	
	arg_end_t *end = (arg_end_t*) arg_end(20);
	void *argtable[] = {help,myip,bounce_opt,listen_opt,proto,source,
			    dest,sport,dport,mcontent,end};

	if(arg_nullcheck(argtable) != 0)
	{
		fprintf(stderr, "error: insufficient memory");
		exitstatus = -1;
		goto exit_prog;
	}

	/* parse and act */
	int nerrors = arg_parse(argc,argv,argtable);
	if(nerrors == 0)
	{
		
		char sourceipbuf[INET6_ADDRSTRLEN];
		size_t contentlen = 0;
		char message_content[MAX_MESSAGELEN + 1];

		/* get glossary */
		if(help->count)
		{
			arg_print_glossary(stdout, argtable, "%-25s %s\n");
		}

		/* get current IP address */
		else if(myip->count)
		{
			if(getmyip(sourceipbuf) == 0)
			{
				printf("Your packets will have the source IP address %s\n", sourceipbuf);
			}
			else
			{
				fprintf(stderr, "error: could not get your IP address.\n");
				exitstatus = -1;
				goto exit_prog;
			}
		}
		
		/* start bouncer */
		else if(bounce_opt->count)
		{
			if(!proto->count)
			{
				fprintf(stderr, "error: expected <protocol> specified.\n");
				exitstatus = -1;
				goto exit_prog;
			}
			
			enum Protocol protocol = parse_protocol(proto->filename[0]);
			if(protocol  == proto_UDP)
			{
				if(!sport->count)
				{
					fprintf(stderr, "error: expected <srcport> specified.\n");
					exitstatus = -1;
					goto exit_prog;
				}

				printf("Starting bouncer for UDP packets on port %u...\n", sport->ival[0]);
				
				/* start_udp_listener(sport->ival[0], bounce_udp_packet);*/
			}
			else
			{
				fprintf(stderr, "Bouncing for %s packets is not supported.\n", proto->filename[0]);
				exitstatus = -1;
				goto exit_prog;
			}
		}
		
		/* start listener */
		else if(listen_opt->count)
		{
			if(!proto->count)
			{
				fprintf(stderr, "error: expected <protocol> specified.\n");
				exitstatus = -1;
				goto exit_prog;
			}
			
			enum Protocol protocol = parse_protocol(proto->filename[0]);
			if(protocol  == proto_UDP)
			{
				if(!sport->count)
				{
					fprintf(stderr, "error: expected <srcport> specified.\n");
					exitstatus = -1;
					goto exit_prog;
				}

				printf("Starting listener for UDP packets on port %u...\n", sport->ival[0]);
				
				char filter[FILTER_BUFLEN];
				memset(filter, 0, FILTER_BUFLEN);
				sprintf(filter, "udp dst port %i", sport->ival[0]);

				start_listener(filter, print_udp_packet);
				/* start_udp_listener(sport->ival[0], print_packet);*/
			}
			else
			{
				fprintf(stderr, "Listening for %s packets is not supported.\n", proto->filename[0]);
				exitstatus = -1;
				goto exit_prog;
			}
		}


		/* send packet */
		else
		{
			/* take into account stdin reading if necessary */
			if(!mcontent->count)
			{
				contentlen = read(STDIN_FILENO, message_content, MAX_MESSAGELEN);
				if(contentlen < 0)
				{
					fprintf(stderr, "error: could not read message from stdin.\n");
					perror("read");
					exitstatus = -1;
					goto exit_prog;

				}
				message_content[contentlen] = '\0';
			}
			else
			{
				int tempstrlen = strlen(mcontent->sval[0]);
				contentlen = tempstrlen > MAX_MESSAGELEN ? MAX_MESSAGELEN : tempstrlen;
				memcpy(message_content, mcontent->sval[0], contentlen);
				message_content[contentlen] = '\0';
			}

			if(!proto->count || !dest->count)
			{
				fprintf(stderr, "error: expected <protocol> and <dest> specified.\n");
				exitstatus = -1;
				goto exit_prog;
			}
			
			if(!source->count)
			{
				if(getmyip(sourceipbuf) != 0)
				{
					fprintf(stderr, "error: could not get your IP address.\n");
					exitstatus = -1;
					goto exit_prog;
				}
			}
			else
			{
				strncpy(sourceipbuf, source->filename[0], INET6_ADDRSTRLEN);
			}


			enum Protocol protocol = parse_protocol(proto->filename[0]);
			if(protocol  == proto_ICMP)
			{
				time_t t;
				if(time(&t) == -1)
				{
					fprintf(stderr, "error: could not get timestamp.\n");
					exitstatus = -1;
					goto exit_prog;
				}

				printf("Sending ICMP ping packet...\nSource -> %s\n"
							       "Destination -> %s\n"
							       "Message -> %i\n",
							       sourceipbuf,
							       dest->filename[0],
							       (int) t);

				/* construct ICMP header */
				int err;
				int payloadsize = sizeof(icmpheader_t) + sizeof(time_t);
				char ip_payload[payloadsize];
				
				/* copy in timestamp */
				/* we must do this first for the checksum calculation */
				t = htonl(t);
				memcpy(ip_payload + sizeof(icmpheader_t), &t, sizeof(time_t));
				
				/* identifier is lower 16 bits,
				   sequence number is upper 16 bits */ 
				uint32_t rest = htons(0x00);
				rest <<= 16;
				rest |= htons(0x7b);

				if((err = fill_icmp_header((icmpheader_t*) ip_payload, 8, 0, rest, sizeof(time_t))) != 0)
				{
					fprintf(stderr, "error: could not fill icmp header, returned %i.\n", err);
					exitstatus = -1;
					goto exit_prog;
				}


				/* send the ip packet */
				ipheader_t iph;
				iph.ip_p = 1; /* ICMP */
				inet_aton(sourceipbuf, (struct in_addr*) &iph.ip_src);
				inet_aton(dest->filename[0], (struct in_addr*) &iph.ip_dst);
				if((err = send_ip_packet(&iph, ip_payload, payloadsize)) != 0)
				{
					fprintf(stderr, "error: could not send ip packet, returned %i.\n", err);
					exitstatus = -1;
					goto exit_prog;
				}
			}
			else if(protocol  == proto_UDP)
			{
				/* get port info */
				unsigned short srcport = sport->count ? (unsigned short) sport->ival[0] : 0;
				if(!dport->count)
				{
					fprintf(stderr, "error: <dstport> specified.\n");
					exitstatus = -1;
					goto exit_prog;
				}
				unsigned short dstport = (unsigned short) dport->ival[0];

				printf("Sending UDP packet...\nSource -> %s:%i\n"
							       "Destination -> %s:%i\n"
							       "Message Length -> %u bytes\n",
							       sourceipbuf, srcport,
							       dest->filename[0], dstport,
							       (unsigned int) contentlen);


				/* construct UDP header */
				int err;
				int payloadsize = sizeof(udpheader_t) + contentlen;
				char ip_payload[payloadsize];

				if((err = fill_udp_header((udpheader_t*) ip_payload, srcport, dstport, contentlen)) != 0)
				{
					fprintf(stderr, "error: could not fill udp header, returned %i.\n", err);
					exitstatus = -1;
					goto exit_prog;
				}

		
				/* set up IP payload */
				memcpy(ip_payload + sizeof(udpheader_t), message_content, contentlen);

				/* send the ip packet */
				ipheader_t iph;
				iph.ip_p = 17; /* UDP */
				inet_aton(sourceipbuf, (struct in_addr*) &iph.ip_src);
				inet_aton(dest->filename[0], (struct in_addr*) &iph.ip_dst);
				if((err = send_ip_packet(&iph, ip_payload, payloadsize)) != 0)
				{
					fprintf(stderr, "error: could not send ip packet, returned %i.\n", err);
					exitstatus = -1;
					goto exit_prog;
				}
			}
			else if(protocol  == proto_TCP)
			{
				printf("TCP currently not supported.\n");
			}
			else
			{
				fprintf(stderr, "error: protocol %s is not supported.\n", proto->filename[0]);
			}
	
			
		}

	}
	else
	{
		arg_print_errors(stdout, end, argv[0]);
		exitstatus = -1;
		goto exit_prog;
	}

exit_prog:
	arg_freetable(argtable, sizeof(argtable)/sizeof(argtable[0]));
	exit(exitstatus);
}
示例#6
0
int main(int argc, char **argv)
{
  int xx, i;
#ifdef STOP_UAC
  int nvpair[2];
#endif
  char buf[520], s[25];
  FILE *f;
#ifndef ENABLE_STRIP
  struct rlimit cdlim;
#endif

  /* Don't allow Eggdrop to run as root. */
  if (((int) getuid() == 0) || ((int) geteuid() == 0))
    fatal("ERROR: Eggdrop will not run as root!", 0);

#ifndef ENABLE_STRIP
  cdlim.rlim_cur = RLIM_INFINITY;
  cdlim.rlim_max = RLIM_INFINITY;
  setrlimit(RLIMIT_CORE, &cdlim);
#endif

#include "patch.h"
  /* Version info! */
  egg_snprintf(ver, sizeof ver, "eggdrop v%s", egg_version);
  egg_snprintf(version, sizeof version,
               "Eggdrop v%s (C) 1997 Robey Pointer (C) 2005 Eggheads",
               egg_version);
  /* Now add on the patchlevel (for Tcl) */
  sprintf(&egg_version[strlen(egg_version)], " %u", egg_numver);
  strcat(egg_version, egg_xtra);

#ifdef STOP_UAC
  nvpair[0] = SSIN_UACPROC;
  nvpair[1] = UAC_NOPRINT;
  setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0);
#endif

  /* Set up error / signal traps. */
  setup_signal_traps();

  /* Initialize a few variables before main loop. */
  cache_miss = 0;
  cache_hit  = 0;
  chanset    = NULL;
  now        = time(NULL);

  egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
  lastmin = nowtm.tm_min;

  /* Initialize random number generator. */
  srandom((unsigned int) (now % (getpid() + getppid())));

  init_mem();
  init_language(1);

  /* Process command line arguments. */
  process_args(argc, argv);

  printf("\n%s\n", version);

  init_dcc_max();
  init_userent();
  logfile_init(0);
  init_bots();
  init_net();
  init_modules();

  if (backgrd)
    bg_prepare_split();

  init_tcl(argc, argv);
  init_language(0);
  help_init();
  traffic_init();
  logfile_init(1);

#ifdef STATIC
  link_statics();
#endif

  strncpyz(s, ctime(&now), sizeof s);
  strcpy(&s[11], &s[20]);
  putlog(LOG_ALL, "*", "--- Loading %s (%s)", ver, s);

  /* Read configuration data. */
  readconfig();

  /* Check for encryption module. */
  if (!encrypt_pass) {
    printf(MOD_NOCRYPT);
    bg_send_quit(BG_ABORT);
    exit(1);
  }

  putlog(LOG_MISC, "*", "=== %s: %d channels, %d users.", botnetnick,
         count_channels(), count_users(userlist));

  if (!pid_file[0])
    egg_snprintf(pid_file, sizeof pid_file, "pid.%s", botnetnick);

  /* Check for pre-existing eggdrop! */
  f = fopen(pid_file, "r");
  if (f != NULL) {
    fgets(s, 10, f);
    xx = atoi(s);
    kill(xx, SIGCHLD); /* Meaningless kill to determine if PID is used. */
    if (errno != ESRCH) {
      printf(EGG_RUNNING1, botnetnick);
      printf(EGG_RUNNING2, pid_file);
      bg_send_quit(BG_ABORT);
      exit(1);
    }
  }

  /* Move into background? */
  if (backgrd) {
#ifndef CYGWIN_HACKS
    bg_do_split();
  }
  else {
#endif
    xx = getpid();
    if (xx != 0) {
      FILE *fp;

      /* Write PID to file. */
      unlink(pid_file);
      fp = fopen(pid_file, "w");
      if (fp != NULL) {
        fprintf(fp, "%u\n", xx);
        if (fflush(fp)) {
          /* Let the bot live since this doesn't appear to be a botchk. */
          printf("Cannot not write to '%s' (PID file).\n", pid_file);
          fclose(fp);
          unlink(pid_file);
        }
        else
          fclose(fp);
      }
      else
        printf("Cannot not write to '%s' (PID file).\n", pid_file);
#ifdef CYGWIN_HACKS
      printf("Launched into the background (PID: %d)\n\n", xx);
#endif
    }
  }

  use_stderr = 0;               /* Stop writing to stderr now */
  if (backgrd) {
    /* Ok, try to disassociate from controlling terminal (finger cross) */
#if defined(HAVE_SETPGID) && !defined(CYGWIN_HACKS)
    setpgid(0, 0);
#endif

    /* Tcl wants the stdin, stdout and stderr file handles kept open. */
    freopen("/dev/null", "r", stdin);
    freopen("/dev/null", "w", stdout);
    freopen("/dev/null", "w", stderr);

#ifdef CYGWIN_HACKS
    FreeConsole();
#endif
  }

  /* Terminal emulating dcc chat */
  if (!backgrd && term_z) {
    int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info));

    dcc[n].addr = iptolong(getmyip());
    dcc[n].sock = STDOUT;
    dcc[n].timeval = now;
    dcc[n].u.chat->con_flags = conmask;
    dcc[n].u.chat->strip_flags = STRIP_ALL;
    dcc[n].status = STAT_ECHO;
    strcpy(dcc[n].nick, "HQ");
    strcpy(dcc[n].host, "llama@console");
    /* HACK: Workaround not to pass literal "HQ" as a non-const arg */
    dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
    /* Make sure there's an innocuous HQ user if needed */
    if (!dcc[n].user) {
      userlist = adduser(userlist, dcc[n].nick, "none", "-", USER_PARTY);
      dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
    }
    setsock(STDOUT, 0); /* Entry in net table */
    dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n");
    dcc_chatter(n);
  }

  then = now;
  online_since = now;
  autolink_cycle(NULL); /* Hurry and connect to tandem bots. */
  add_help_reference("cmds1.help");
  add_help_reference("cmds2.help");
  add_help_reference("core.help");

  /* Create hooks. */
  add_hook(HOOK_SECONDLY, (Function) core_secondly);
  add_hook(HOOK_MINUTELY, (Function) core_minutely);
  add_hook(HOOK_HOURLY, (Function) core_hourly);
  add_hook(HOOK_REHASH, (Function) event_rehash);
  add_hook(HOOK_PRE_REHASH, (Function) event_prerehash);
  add_hook(HOOK_USERFILE, (Function) event_save);
  add_hook(HOOK_BACKUP, (Function) backupuserfile);
  add_hook(HOOK_DAILY, (Function) event_logfile);
  add_hook(HOOK_DAILY, (Function) traffic_reset);
  add_hook(HOOK_LOADED, (Function) event_loaded);

  call_hook(HOOK_LOADED);

  debug0("main: entering loop");
  while (1) {
    int socket_cleanup = 0;

#ifdef USE_TCL_EVENTS
    /* Process a single Tcl event. */
    Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
#endif

    now = time(NULL);
    random();

    /* Every second... */
    if (now != then) {
      call_hook(HOOK_SECONDLY);
      then = now;
    }

    /* Only do this every so often. */
    if (!socket_cleanup) {
      socket_cleanup = 5;

      /* Remove dead dcc entries. */
      dcc_remove_lost();

      /* Check for server or dcc activity. */
      dequeue_sockets();
    }
    else {
      socket_cleanup--;
    }

    /* Free unused structures. */
    garbage_collect();

    xx = sockgets(buf, &i);
    if (xx >= 0) { /* Non-error */
      int idx;

      for (idx = 0; idx < dcc_total; idx++) {
        if (dcc[idx].sock != xx)
          continue;

        if (dcc[idx].type && dcc[idx].type->activity) {
          traffic_update_in(dcc[idx].type, (strlen(buf) + 1)); /* Traffic stats. */
          dcc[idx].type->activity(idx, buf, i);
        }
        else {
          putlog(LOG_MISC, "*", "!!! untrapped dcc activity: type %s, sock %d",
                 dcc[idx].type->name, dcc[idx].sock);
        }

        break;
      }
    }
    else if (xx == -1) { /* EOF */
      int idx;

      if (i == STDOUT && !backgrd)
        fatal("END OF FILE ON TERMINAL", 0);

      for (idx = 0; idx < dcc_total; idx++) {
        if (dcc[idx].sock != i)
          continue;

        if (dcc[idx].type && dcc[idx].type->eof) {
          dcc[idx].type->eof(idx);
        }
        else {
          putlog(LOG_MISC, "*",
                 "*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED",
                 i, dcc[idx].type ? dcc[idx].type->name : "*UNKNOWN*");
          killsock(i);
          lostdcc(idx);
        }

        idx = dcc_total + 1;
      }

      if (idx == dcc_total) {
        putlog(LOG_MISC, "*",
               "(@) EOF socket %d, not a dcc socket, not anything.", i);
        close(i);
        killsock(i);
      }
    }
    else if (xx == -2 && errno != EINTR) { /* select() error */
      putlog(LOG_MISC, "*", "* Socket error #%d; recovering.", errno);
      for (i = 0; i < dcc_total; i++) {
        if ((fcntl(dcc[i].sock, F_GETFD, 0) == -1) && (errno == EBADF)) {
          putlog(LOG_MISC, "*",
                 "DCC socket %d (type %d, name '%s') expired -- pfft",
                 dcc[i].sock, dcc[i].type, dcc[i].nick);
          killsock(dcc[i].sock);
          lostdcc(i);
          i--;
        }
      }
    }
    else if (xx == -3) {
      call_hook(HOOK_IDLE);
      socket_cleanup = 0;       /* If we've been idle, cleanup & flush */
    }

    if (do_restart) {
      if (do_restart == -2) {
        rehash();
      }
      else {
        int f = 1;
        module_entry *p;
        Function startfunc;
        char name[256];


        check_tcl_event("prerestart");

        /* Unload as many modules as possible */
        while (f) {
          f = 0;

          for (p = module_list; p != NULL; p = p->next) {
            dependancy *d = dependancy_list;
            int ok = 1;

            while (ok && d) {
              if (d->needed == p)
                ok = 0;

              d = d->next;
            }
            if (ok) {
              strcpy(name, p->name);

              if (module_unload(name, botnetnick) == NULL) {
                f = 1;
                break;
              }
            }
          }
        }

        /* Make sure we don't have any modules left hanging around other than
         * "eggdrop" and the two that are supposed to be.
         */
        for (f = 0, p = module_list; p; p = p->next) {
          if (strcmp(p->name, "eggdrop") && strcmp(p->name, "encryption") &&
              strcmp(p->name, "uptime")) {
            f++;
          }
        }
        if (f != 0) {
          putlog(LOG_MISC, "*", MOD_STAGNANT);
        }

        /* Flush log files to disk. */
        flushlogs();

        /* Clean up Tcl stuff. */
        kill_tcl();

        /* Initialize stuff again. */
        init_tcl(argc, argv);
        init_language(0);
        help_init();
        traffic_init();
        logfile_init(1);

        /* This resets our modules which we didn't unload (encryption and uptime). */
        for (p = module_list; p; p = p->next) {
          if (p->funcs) {
            startfunc = p->funcs[MODCALL_START];
            startfunc(NULL);
          }
        }

        rehash();
        restart_chons();
        call_hook(HOOK_LOADED);
      }

      do_restart = 0;
    }
  }
}
示例#7
0
文件: main.c 项目: Abysim/NyanLion
int main(int arg_c, char **arg_v)
{
  int i, xx;
  char s[25];
  FILE *f;
  struct sigaction sv;
  struct chanset_t *chan;
#ifdef DEBUG
  struct rlimit cdlim;
#endif
#ifdef STOP_UAC
  int nvpair[2];
#endif

/* Make sure it can write core, if you make debug. Else it's pretty
 * useless (dw)
 *
 * Only allow unlimited size core files when compiled with DEBUG defined.
 * This is not a good idea for normal builds -- in these cases, use the
 * default system resource limits instead.
 */
#ifdef DEBUG
  cdlim.rlim_cur = RLIM_INFINITY;
  cdlim.rlim_max = RLIM_INFINITY;
  setrlimit(RLIMIT_CORE, &cdlim);
#endif

#ifdef DEBUG_CONTEXT
  /* Initialise context list */
  for (i = 0; i < 16; i++)
    Context;
#endif

/* Include patch.h header for patch("...") */
#include "patch.h"

  argc = arg_c;
  argv = arg_v;

  /* Version info! */
  egg_snprintf(ver, sizeof ver, "eggdrop v%s", egg_version);
  egg_snprintf(version, sizeof version,
               "Eggdrop v%s (C) 1997 Robey Pointer (C) 2011 Eggheads",
               egg_version);
  /* Now add on the patchlevel (for Tcl) */
  sprintf(&egg_version[strlen(egg_version)], " %u", egg_numver);
  strcat(egg_version, egg_xtra);

/* For OSF/1 */
#ifdef STOP_UAC
  /* Don't print "unaligned access fixup" warning to the user */
  nvpair[0] = SSIN_UACPROC;
  nvpair[1] = UAC_NOPRINT;
  setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0);
#endif

  /* Set up error traps: */
  sv.sa_handler = got_bus;
  sigemptyset(&sv.sa_mask);
#ifdef SA_RESETHAND
  sv.sa_flags = SA_RESETHAND;
#else
  sv.sa_flags = 0;
#endif
  sigaction(SIGBUS, &sv, NULL);
  sv.sa_handler = got_segv;
  sigaction(SIGSEGV, &sv, NULL);
#ifdef SA_RESETHAND
  sv.sa_flags = 0;
#endif
  sv.sa_handler = got_fpe;
  sigaction(SIGFPE, &sv, NULL);
  sv.sa_handler = got_term;
  sigaction(SIGTERM, &sv, NULL);
  sv.sa_handler = got_hup;
  sigaction(SIGHUP, &sv, NULL);
  sv.sa_handler = got_quit;
  sigaction(SIGQUIT, &sv, NULL);
  sv.sa_handler = SIG_IGN;
  sigaction(SIGPIPE, &sv, NULL);
  sv.sa_handler = got_ill;
  sigaction(SIGILL, &sv, NULL);
  sv.sa_handler = got_alarm;
  sigaction(SIGALRM, &sv, NULL);

  /* Initialize variables and stuff */
  now = time(NULL);
  chanset = NULL;
  egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
  lastmin = nowtm.tm_min;
  srandom((unsigned int) (now % (getpid() + getppid())));
  init_mem();
  init_language(1);
  if (argc > 1)
    for (i = 1; i < argc; i++)
      do_arg(argv[i]);

  printf("\n%s\n", version);

#ifndef CYGWIN_HACKS
  /* Don't allow eggdrop to run as root
   * This check isn't useful under cygwin and has been
   * reported to cause trouble in some situations.
   */
  if (((int) getuid() == 0) || ((int) geteuid() == 0))
    fatal("ERROR: Eggdrop will not run as root!", 0);
#endif

#ifndef REPLACE_NOTIFIER
  init_threaddata(1);
#endif
  init_userent();
  init_misc();
  init_bots();
  init_modules();
  if (backgrd)
    bg_prepare_split();
  init_tcl(argc, argv);
  init_language(0);
#ifdef STATIC
  link_statics();
#endif
  strncpyz(s, ctime(&now), sizeof s);
  strcpy(&s[11], &s[20]);
  putlog(LOG_ALL, "*", "--- Loading %s (%s)", ver, s);
  chanprog();
  if (!encrypt_pass) {
    printf(MOD_NOCRYPT);
    bg_send_quit(BG_ABORT);
    exit(1);
  }
  i = 0;
  for (chan = chanset; chan; chan = chan->next)
    i++;
  putlog(LOG_MISC, "*", "=== %s: %d channels, %d users.",
         botnetnick, i, count_users(userlist));
  cache_miss = 0;
  cache_hit = 0;
  if (!pid_file[0])
    egg_snprintf(pid_file, sizeof pid_file, "pid.%s", botnetnick);

  /* Check for pre-existing eggdrop! */
  f = fopen(pid_file, "r");
  if (f != NULL) {
    fgets(s, 10, f);
    xx = atoi(s);
    i = kill(xx, SIGCHLD);      /* Meaningless kill to determine if pid
                                 * is used */
    if (i == 0 || errno != ESRCH) {
      printf(EGG_RUNNING1, botnetnick);
      printf(EGG_RUNNING2, pid_file);
      bg_send_quit(BG_ABORT);
      exit(1);
    }
  }

  /* Move into background? */
  if (backgrd) {
    bg_do_split();
  } else {                        /* !backgrd */
    xx = getpid();
    if (xx != 0) {
      FILE *fp;

      /* Write pid to file */
      unlink(pid_file);
      fp = fopen(pid_file, "w");
      if (fp != NULL) {
        fprintf(fp, "%u\n", xx);
        if (fflush(fp)) {
          /* Let the bot live since this doesn't appear to be a botchk */
          printf(EGG_NOWRITE, pid_file);
          fclose(fp);
          unlink(pid_file);
        } else
          fclose(fp);
      } else
        printf(EGG_NOWRITE, pid_file);
    }
  }

  use_stderr = 0;               /* Stop writing to stderr now */
  if (backgrd) {
    /* Ok, try to disassociate from controlling terminal (finger cross) */
#ifdef HAVE_SETPGID
    setpgid(0, 0);
#endif
    /* Tcl wants the stdin, stdout and stderr file handles kept open. */
    freopen("/dev/null", "r", stdin);
    freopen("/dev/null", "w", stdout);
    freopen("/dev/null", "w", stderr);
#ifdef CYGWIN_HACKS
    FreeConsole();
#endif
  }

  /* Terminal emulating dcc chat */
  if (!backgrd && term_z) {
    int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info));

    dcc[n].addr = iptolong(getmyip());
    dcc[n].sock = STDOUT;
    dcc[n].timeval = now;
    dcc[n].u.chat->con_flags = conmask;
    dcc[n].u.chat->strip_flags = STRIP_ALL;
    dcc[n].status = STAT_ECHO;
    strcpy(dcc[n].nick, "HQ");
    strcpy(dcc[n].host, "llama@console");
    /* HACK: Workaround not to pass literal "HQ" as a non-const arg */
    dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
    /* Make sure there's an innocuous HQ user if needed */
    if (!dcc[n].user) {
      userlist = adduser(userlist, dcc[n].nick, "none", "-", USER_PARTY);
      dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
    }
    setsock(STDOUT, 0);          /* Entry in net table */
    dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n");
    dcc_chatter(n);
  }

  then = now;
  online_since = now;
  autolink_cycle(NULL);         /* Hurry and connect to tandem bots */
  add_help_reference("cmds1.help");
  add_help_reference("cmds2.help");
  add_help_reference("core.help");
  add_hook(HOOK_SECONDLY, (Function) core_secondly);
  add_hook(HOOK_MINUTELY, (Function) core_minutely);
  add_hook(HOOK_HOURLY, (Function) core_hourly);
  add_hook(HOOK_REHASH, (Function) event_rehash);
  add_hook(HOOK_PRE_REHASH, (Function) event_prerehash);
  add_hook(HOOK_USERFILE, (Function) event_save);
  add_hook(HOOK_BACKUP, (Function) backup_userfile);
  add_hook(HOOK_DAILY, (Function) event_logfile);
  add_hook(HOOK_DAILY, (Function) event_resettraffic);
  add_hook(HOOK_LOADED, (Function) event_loaded);

  call_hook(HOOK_LOADED);

  debug0("main: entering loop");
  while (1) {
    mainloop(1);
  }
}
示例#8
0
/* Create a new listening port (or destroy one)
 *
 * listen <port> bots/all/users [mask]
 * listen <port> script <proc> [flag]
 * listen <port> off
 */
static int tcl_listen(ClientData cd, Tcl_Interp *irp,
                      int argc, char *argv[])
{
  int i, j, idx = -1, port, realport;
  char s[11], msg[256];
  struct portmap *pmap = NULL, *pold = NULL;

  BADARGS(3, 5, " port type ?mask?/?proc ?flag??");

  port = realport = atoi(argv[1]);
  for (pmap = root; pmap; pold = pmap, pmap = pmap->next)
    if (pmap->realport == port) {
      port = pmap->mappedto;
      break;
  }
  for (i = 0; i < dcc_total; i++)
    if ((dcc[i].type == &DCC_TELNET) && (dcc[i].port == port))
      idx = i;
  if (!egg_strcasecmp(argv[2], "off")) {
    if (pmap) {
      if (pold)
        pold->next = pmap->next;
      else
        root = pmap->next;
      nfree(pmap);
    }
    /* Remove */
    if (idx < 0) {
      Tcl_AppendResult(irp, "no such listen port is open", NULL);
      return TCL_ERROR;
    }
    killsock(dcc[idx].sock);
    lostdcc(idx);
    return TCL_OK;
  }
  if (idx < 0) {
    /* Make new one */
    if (dcc_total >= max_dcc) {
      Tcl_AppendResult(irp, "No more DCC slots available.", NULL);
      return TCL_ERROR;
    }
    /* Try to grab port */
    j = port + 20;
    i = -1;
    while (port < j && i < 0) {
      i = open_listen(&port);
      if (i == -1)
        port++;
      else if (i == -2)
        break;
    }
    if (i == -1) {
      egg_snprintf(msg, sizeof msg, "Couldn't listen on port '%d' on the "
                   "given address. Please make sure 'my-ip' is set correctly, "
                   "or try a different port.", realport);
      Tcl_AppendResult(irp, msg, NULL);
      return TCL_ERROR;
    } else if (i == -2) {
      Tcl_AppendResult(irp, "Couldn't assign the requested IP. Please make "
                       "sure 'my-ip' is set properly.", NULL);
      return TCL_ERROR;
    }
    idx = new_dcc(&DCC_TELNET, 0);
    dcc[idx].addr = iptolong(getmyip());
    dcc[idx].port = port;
    dcc[idx].sock = i;
    dcc[idx].timeval = now;
  }
  /* script? */
  if (!strcmp(argv[2], "script")) {
    strcpy(dcc[idx].nick, "(script)");
    if (argc < 4) {
      Tcl_AppendResult(irp, "a proc name must be specified for a script listen", NULL);
      killsock(dcc[idx].sock);
      lostdcc(idx);
      return TCL_ERROR;
    }
    if (argc == 5) {
      if (strcmp(argv[4], "pub")) {
        Tcl_AppendResult(irp, "unknown flag: ", argv[4], ". allowed flags: pub",
                         NULL);
        killsock(dcc[idx].sock);
        lostdcc(idx);
        return TCL_ERROR;
      }
      dcc[idx].status = LSTN_PUBLIC;
    }
    strncpyz(dcc[idx].host, argv[3], UHOSTMAX);
    egg_snprintf(s, sizeof s, "%d", port);
    Tcl_AppendResult(irp, s, NULL);
    return TCL_OK;
  }
  /* bots/users/all */
  if (!strcmp(argv[2], "bots"))
    strcpy(dcc[idx].nick, "(bots)");
  else if (!strcmp(argv[2], "users"))
    strcpy(dcc[idx].nick, "(users)");
  else if (!strcmp(argv[2], "all"))
    strcpy(dcc[idx].nick, "(telnet)");
  if (!dcc[idx].nick[0]) {
    Tcl_AppendResult(irp, "invalid listen type: must be one of ",
                     "bots, users, all, off, script", NULL);
    killsock(dcc[idx].sock);
    dcc_total--;
    return TCL_ERROR;
  }
  if (argc == 4)
    strncpyz(dcc[idx].host, argv[3], UHOSTMAX);
  else
    strcpy(dcc[idx].host, "*");
  egg_snprintf(s, sizeof s, "%d", port);
  Tcl_AppendResult(irp, s, NULL);
  if (!pmap) {
    pmap = nmalloc(sizeof(struct portmap));
    pmap->next = root;
    root = pmap;
  }
  pmap->realport = realport;
  pmap->mappedto = port;
  putlog(LOG_MISC, "*", "Listening at telnet port %d (%s).", port, argv[2]);
  return TCL_OK;
}
示例#9
0
// Process menu input and call functions based on input
void process_menu_input()
{
  char command[BUFF_SIZE];
  char *buffer;
  int index1, index2;
  uint32_t cost;

  // Get the command...
  if (fgets(command, BUFF_SIZE, stdin) == NULL) die ("Input Error");

  buffer = strtok(command, " \n\r\0");
  if (strcmp(command, "help") == 0)
  {
    display_menu_help();
  } 
  else if (strcmp(command, "update") == 0)
  {
    buffer = strtok(NULL, " \n");
    if (buffer == NULL) die("update ERROR invalid input");
    index1 = get_index_from_id(atoi(buffer));
    buffer = strtok(NULL, " \n");
    if (buffer == NULL) die("update ERROR invalid input\n");
    index2 = get_index_from_id(atoi(buffer));
    if (index1 < 0 || index2 < 0) printf("update ERROR invalid id\n");
    else if ((my_server->index != index1 && connect_out[index1].in_use == 0) || connect_out[index2].in_use == 0)
      printf("update ERROR ids must be active\n");
    else
    {
      buffer = strtok(NULL, "\n");
      if (strcmp(buffer, "inf") == 0) cost = INFINITY;
      else cost = atoi(buffer);

      if (cost < 0) printf("update ERROR invalid cost\n");
      else
      {
        // Be sure to update the actual cost if it involves ourselves
        if (index1 == my_server->index)
          route[index2].cost = cost;
        else if (index2 == my_server->index)
           route[index1].cost = cost;

        // Otherwise just update the "cost" distance in our topology
        topology.server[index1].cost[index2] = cost;
        printf("update SUCCESS\n");
        update_route();
      }
    }
  }
  else if (strcmp(command, "disable") == 0)
  {
    buffer = strtok(NULL, "\n");
    index1 = get_index_from_id(atoi(buffer));
    if (index1 < 0) printf("disable ERROR invalid id\n");
    else if (connect_out[index1].in_use == 0) printf("disable ERROR id not in use\n");
    else
    {
      disable_connect(index1);
      printf("disable SUCCESS\n");
    }
  }
  else if (strcmp(command, "crash") == 0)
  {
    for (index1 = 0; index1 < MAX_SERVERS; ++index1)
      disable_connect(index1);
    connect_in.in_use = 0;
    printf("crash SUCCESS\n");
  }
  else if (strcmp(command, "step") == 0)
  {
    if (connect_in.in_use == 0) printf("step ERROR server is crashed\n");
    else
    {
      send_packet_to_neighbors();
      printf("step SUCCESS\n");
    }
  }
  else if (strcmp(command, "display") == 0)
  {
    display_route();
    printf("display SUCCESS\n");
  }
  else if (strcmp(command, "packets") == 0)
  {
    printf("Packets received since last update: %d\npackets SUCCESS\n", packets_rcvd);
    packets_rcvd = 0;
  }
  else if (strcmp(command, "myip") == 0)
  {
    printf("My IP: %s (real: %s)\nmyip SUCCESS\n", char4_to_str(my_server->ip), getmyip());
  }
  else if (strcmp(command, "myport") == 0)
  {
    printf("My Port #: %i\nmyport SUCCESS\n", my_server->port);
  }
  else if (strcmp(command, "cls") == 0)
  {
    clear_screen();
  }
  else if (strcmp(command, "exit") == 0) die ("\t\tGOODBYE :)");
  else printf("Unrecognized command: type help for help\n");
  fflush(NULL);
}