Exemplo n.º 1
0
static serv_state
run_rpc(void)
{
#ifdef HAVE_SIGACTION
  sigset_t smask;
  sigprocmask(SIG_BLOCK, &masked_sigs, &smask);
#else /* not HAVE_SIGACTION */
  int smask = sigblock(MASKED_SIGS);
#endif /* not HAVE_SIGACTION */

  next_softclock = clocktime(NULL);

  amd_state = Run;

  /*
   * Keep on trucking while we are in Run mode.  This state
   * is switched to Quit after all the file systems have
   * been unmounted.
   */
  while ((int) amd_state <= (int) Finishing) {
    struct timeval tvv;
    int nsel;
    time_t now;
    fd_set readfds;

#ifdef HAVE_SVC_GETREQSET
    memmove(&readfds, &svc_fdset, sizeof(svc_fdset));
#else /* not HAVE_SVC_GETREQSET */
    FD_ZERO(&readfds);
# ifdef HAVE_FD_SET_FDS_BITS
    readfds.fds_bits[0] = svc_fds;
# else /* not HAVE_FD_SET_FDS_BITS */
    readfds = svc_fds;
# endif  /* not HAVE_FD_SET_FDS_BITS */
#endif /* not HAVE_SVC_GETREQSET */
    FD_SET(fwd_sock, &readfds);

    checkup();

    /*
     * If the full timeout code is not called,
     * then recompute the time delta manually.
     */
    now = clocktime(NULL);

    if (next_softclock <= now) {
      if (amd_state == Finishing)
	umount_exported();
      tvv.tv_sec = softclock();
    } else {
      tvv.tv_sec = next_softclock - now;
    }
    tvv.tv_usec = 0;

    if (amd_state == Finishing && get_exported_ap(0) == NULL) {
      flush_mntfs();
      amd_state = Quit;
      break;
    }

#ifdef HAVE_FS_AUTOFS
    autofs_add_fdset(&readfds);
#endif /* HAVE_FS_AUTOFS */

    if (tvv.tv_sec <= 0)
      tvv.tv_sec = SELECT_MAXWAIT;
    if (tvv.tv_sec) {
      dlog("Select waits for %ds", (int) tvv.tv_sec);
    } else {
      dlog("Select waits for Godot");
    }

    nsel = do_select(smask, FD_SETSIZE, &readfds, &tvv);

    switch (nsel) {
    case -1:
      if (errno == EINTR) {
	dlog("select interrupted");
	continue;
      }
      plog(XLOG_ERROR, "select: %m");
      break;

    case 0:
      break;

    default:
      /*
       * Read all pending NFS responses at once to avoid having responses
       * queue up as a consequence of retransmissions.
       */
      if (FD_ISSET(fwd_sock, &readfds)) {
	FD_CLR(fwd_sock, &readfds);
	--nsel;
	do {
	  fwd_reply();
	} while (rpc_pending_now() > 0);
      }

#ifdef HAVE_FS_AUTOFS
      if (nsel)
	nsel = autofs_handle_fdset(&readfds, nsel);
#endif /* HAVE_FS_AUTOFS */

      if (nsel) {
	/*
	 * Anything left must be a normal
	 * RPC request.
	 */
#ifdef HAVE_SVC_GETREQSET
	svc_getreqset(&readfds);
#else /* not HAVE_SVC_GETREQSET */
# ifdef HAVE_FD_SET_FDS_BITS
	svc_getreq(readfds.fds_bits[0]);
# else /* not HAVE_FD_SET_FDS_BITS */
	svc_getreq(readfds);
# endif /* not HAVE_FD_SET_FDS_BITS */
#endif /* not HAVE_SVC_GETREQSET */
      }
      break;
    }
  }

#ifdef HAVE_SIGACTION
  sigprocmask(SIG_SETMASK, &smask, NULL);
#else /* not HAVE_SIGACTION */
  (void) sigsetmask(smask);
#endif /* not HAVE_SIGACTION */

  if (amd_state == Quit)
    amd_state = Done;

  return amd_state;
}
Exemplo n.º 2
0
void server_main (void)
{
   static char status;
   static int zignal;

   char ch;
   int i = 0;
   unsigned int len;
   CORE_ADDR mem_addr;

   zignal = valgrind_wait (&status);
   if (VG_MINIMAL_SETJMP(toplevel)) {
      dlog(0, "error caused VG_MINIMAL_LONGJMP to server_main\n");
   }
   while (1) {
      unsigned char sig;
      int packet_len;
      int new_packet_len = -1;
      
      if (resume_reply_packet_needed) {
         /* Send the resume reply to reply to last GDB resume
            request. */
         resume_reply_packet_needed = False;
         prepare_resume_reply (own_buf, status, zignal);
         putpkt (own_buf);
      }

      packet_len = getpkt (own_buf);
      if (packet_len <= 0)
         break;

      i = 0;
      ch = own_buf[i++];
      switch (ch) {
      case 'Q':
         handle_set (own_buf, &new_packet_len);
         break;
      case 'q':
         handle_query (own_buf, &new_packet_len);
         break;
      case 'd':
         /* set/unset debugging is done through valgrind debug level. */
         own_buf[0] = '\0';
         break;
      case 'D':
         reset_valgrind_sink("gdb detaching from process");

         /* When detaching or kill the process, gdb expects to get
            an packet OK back.  Any other output will make gdb
            believes detach did not work. */
         write_ok (own_buf);
         putpkt (own_buf);
         remote_finish (reset_after_error);
         remote_open (VG_(clo_vgdb_prefix));
         myresume (0, 0);
         resume_reply_packet_needed = False;
         return;
      case '!':
         /* We can not use the extended protocol with valgrind,
            because we can not restart the running
            program.  So return unrecognized.  */
         own_buf[0] = '\0';
         break;
      case '?':
         prepare_resume_reply (own_buf, status, zignal);
         break;
      case 'H':
         if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's') {
            unsigned long gdb_id, thread_id;
            
            gdb_id = strtoul (&own_buf[2], NULL, 16);
            thread_id = gdb_id_to_thread_id (gdb_id);
            if (thread_id == 0) {
               write_enn (own_buf);
               break;
            }

            if (own_buf[1] == 'g') {
               general_thread = thread_id;
               set_desired_inferior (1);
            } else if (own_buf[1] == 'c') {
               cont_thread = thread_id;
            } else if (own_buf[1] == 's') {
               step_thread = thread_id;
            }
            
            write_ok (own_buf);
         } else {
            /* Silently ignore it so that gdb can extend the protocol
               without compatibility headaches.  */
            own_buf[0] = '\0';
         }
         break;
      case 'g':
         set_desired_inferior (1);
         registers_to_string (own_buf);
         break;
      case 'G':
         set_desired_inferior (1);
         registers_from_string (&own_buf[1]);
         write_ok (own_buf);
         break;
      case 'P': {
         int regno;
         char *regbytes;
         Bool mod;
         ThreadState *tst;
         regno = strtol(&own_buf[1], NULL, 16);
         regbytes = strchr(&own_buf[0], '=') + 1;
         set_desired_inferior (1);
         tst = (ThreadState *) inferior_target_data (current_inferior);
         /* Only accept changing registers in "runnable state3.
            In fact, it would be ok to change most of the registers
            except a few "sensitive" registers such as the PC, SP, BP.
            We assume we do not need to very specific here, and that we
            can just refuse all of these. */
         if (tst->status == VgTs_Runnable || tst->status == VgTs_Yielding) {
            supply_register_from_string (regno, regbytes, &mod);
            write_ok (own_buf);
         } else {
            /* at least from gdb 6.6 onwards, an E. error
               reply is shown to the user. So, we do an error
               msg which both is accepted by gdb as an error msg
               and is readable by the user. */
            VG_(sprintf) 
               (own_buf,
"E.\n"
"ERROR changing register %s regno %d\n"
"gdb commands changing registers (pc, sp, ...) (e.g. 'jump',\n"
"set pc, calling from gdb a function in the debugged process, ...)\n"
"can only be accepted if the thread is VgTs_Runnable or VgTs_Yielding state\n"
"Thread status is %s\n",
                find_register_by_number (regno)->name, regno,
                VG_(name_of_ThreadStatus)(tst->status));
            if (VG_(clo_verbosity) > 1)
               VG_(umsg) ("%s\n", own_buf);
         }
         break;            
      }
      case 'm':
         decode_m_packet (&own_buf[1], &mem_addr, &len);
         if (valgrind_read_memory (mem_addr, mem_buf, len) == 0)
            convert_int_to_ascii (mem_buf, own_buf, len);
         else
            write_enn (own_buf);
         break;
      case 'M':
         decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
         if (valgrind_write_memory (mem_addr, mem_buf, len) == 0)
            write_ok (own_buf);
         else
            write_enn (own_buf);
         break;
      case 'X':
         if (decode_X_packet (&own_buf[1], packet_len - 1,
                              &mem_addr, &len, mem_buf) < 0
             || valgrind_write_memory (mem_addr, mem_buf, len) != 0)
            write_enn (own_buf);
         else
            write_ok (own_buf);
         break;
      case 'C':
         convert_ascii_to_int (own_buf + 1, &sig, 1);
         if (target_signal_to_host_p (sig))
            zignal = target_signal_to_host (sig);
         else
            zignal = 0;
         set_desired_inferior (0);
         myresume (0, zignal);
         return; // return control to valgrind
      case 'S':
         convert_ascii_to_int (own_buf + 1, &sig, 1);
         if (target_signal_to_host_p (sig))
            zignal = target_signal_to_host (sig);
         else
            zignal = 0;
         set_desired_inferior (0);
         myresume (1, zignal);
         return; // return control to valgrind
      case 'c':
         set_desired_inferior (0);
         myresume (0, 0);
         return; // return control to valgrind
      case 's':
         set_desired_inferior (0);
         myresume (1, 0);
         return; // return control to valgrind
      case 'Z': {
         char *lenptr;
         char *dataptr;
         CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16);
         int zlen = strtol (lenptr + 1, &dataptr, 16);
         char type = own_buf[1];
         
         if (type < '0' || type > '4') {
            /* Watchpoint command type unrecognized. */
            own_buf[0] = '\0';
         } else {
            int res;
            
            res = valgrind_insert_watchpoint (type, addr, zlen);
            if (res == 0)
               write_ok (own_buf);
            else if (res == 1)
               /* Unsupported.  */
               own_buf[0] = '\0';
            else
               write_enn (own_buf);
         }
         break;
      }
      case 'z': {
         char *lenptr;
         char *dataptr;
         CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16);
         int zlen = strtol (lenptr + 1, &dataptr, 16);
         char type = own_buf[1];
         
         if (type < '0' || type > '4') {
            /* Watchpoint command type unrecognized. */
            own_buf[0] = '\0';
         } else {
            int res;
            
            res = valgrind_remove_watchpoint (type, addr, zlen);
            if (res == 0)
               write_ok (own_buf);
            else if (res == 1)
               /* Unsupported.  */
               own_buf[0] = '\0';
            else
               write_enn (own_buf);
         }
         break;
      }
      case 'k':
         kill_request("Gdb request to kill this process\n");
         break;
      case 'T': {
         unsigned long gdb_id, thread_id;
         
         gdb_id = strtoul (&own_buf[1], NULL, 16);
         thread_id = gdb_id_to_thread_id (gdb_id);
         if (thread_id == 0) {
            write_enn (own_buf);
            break;
         }

         if (valgrind_thread_alive (thread_id))
            write_ok (own_buf);
         else
            write_enn (own_buf);
         break;
      }
      case 'R':
         /* Restarting the inferior is only supported in the
            extended protocol.
            => It is a request we don't understand.  Respond with an
            empty packet so that gdb knows that we don't support this
            request.  */
         own_buf[0] = '\0';
         break;
      case 'v':
         /* Extended (long) request.  */
         handle_v_requests (own_buf, &status, &zignal);
         break;
      default:
         /* It is a request we don't understand.  Respond with an
            empty packet so that gdb knows that we don't support this
            request.  */
         own_buf[0] = '\0';
         break;
      }

      if (new_packet_len != -1)
         putpkt_binary (own_buf, new_packet_len);
      else
         putpkt (own_buf);
      
      if (status == 'W')
         VG_(umsg) ("\nChild exited with status %d\n", zignal);
      if (status == 'X')
         VG_(umsg) ("\nChild terminated with signal = 0x%x (%s)\n",
                    target_signal_to_host (zignal),
                    target_signal_to_name (zignal));
      if (status == 'W' || status == 'X') {
         VG_(umsg) ("Process exiting\n");
         VG_(exit) (0);
      }
   }

   /* We come here when getpkt fails => close the connection,
      and re-open. Then return control to valgrind.
      We return the control to valgrind as we assume that
      the connection was closed due to vgdb having finished
      to execute a command. */
   if (VG_(clo_verbosity) > 1)
      VG_(umsg) ("Remote side has terminated connection.  "
                 "GDBserver will reopen the connection.\n");
   remote_finish (reset_after_error);
   remote_open (VG_(clo_vgdb_prefix)); 
   myresume (0, 0);
   resume_reply_packet_needed = False;
   return;
}
Exemplo n.º 3
0
int do_worker_job(void)
{
    if (settings.shift_table_type == TABLE_NO_SHIFT)
    {
        create_new_tables();
    }

    struct worker *worker = &settings.workers[settings.worker_id];

    while (true)
    {
        worker_looper();

        char     *sql;
        uint32_t length;
        int      ret;
        bool     empty = false;

        ret = queue_pop(&worker->queue, (void **)&sql, &length);
        if (ret == -1)
        {
            empty = true;
        }
        else if (ret < 0)
        {
            log_error("queue_pop error: %d", ret);

            empty = true;
        }

        if (empty)
        {
            ret = queue_pop(&settings.cache_queue, (void **)&sql, &length);

            if (ret >= 0)
            {
                empty = false;
            }
            else if (ret < -1)
            {
                log_error("queue_pop error: %d", ret);
            }
        }

        if (empty)
        {
            wait_for_notify(worker);

            continue;
        }

        log_debug("worker: %d, sql: %s", settings.worker_id, sql);

        bool is_insert = true;
        if (strncmp(sql, "INSERT", 6) != 0)
            is_insert = false;

        ret = db_safe_query(sql, length - 1);

        if (ret < 0)
        {
            if (is_insert)
            {
                log_error("worker: %d, insert fail: %s", \
                        settings.worker_id, db_error());

                ++insert_db_fail_count;
            }
            else
            {
                log_error("worker: %d, exec sql: %s fail: %s", \
                        settings.worker_id, sql, db_error());

                ++exec_sql_fail_count;
            }

            if (ret < -1 || (ret == -1 && \
                        queue_push(&settings.cache_queue, sql, length) < 0))
            {
                if (is_insert)
                {
                    dlog(settings.fail_insert_log, "%s;", sql);
                }
            }

            if (ret == -1)
            {
                usleep(WORKER_BAD_CONN_USLEEP_TIME);
            }
        }
        else
        {
            if (is_insert)
            {
                int rows = db_affected_rows();
                insert_db_succ_count += rows;
            }
            else
            {
                exec_sql_succ_count += 1;
            }
        }
    }

    return 0;
}
Exemplo n.º 4
0
/* If reason is init_reason, creates the connection resources (e.g.
      the FIFOs) to allow a gdb connection to be detected by polling
      using remote_desc_activity.
   Otherwise (other reasons):
       If connection with gdb not yet opened, opens the connection with gdb.
       reads gdb remote protocol packets and executes the requested commands.
*/
static void call_gdbserver ( ThreadId tid , CallReason reason)
{
   ThreadState*     tst = VG_(get_ThreadState)(tid);
   int stepping;
   Addr saved_pc;

   dlog(1, 
        "entering call_gdbserver %s ... pid %d tid %d status %s "
        "sched_jmpbuf_valid %d\n",
        ppCallReason (reason),
        VG_(getpid) (), tid, VG_(name_of_ThreadStatus)(tst->status),
        tst->sched_jmpbuf_valid);

   vg_assert(VG_(is_valid_tid)(tid));
   saved_pc = VG_(get_IP) (tid);

   if (gdbserver_exited) {
      dlog(0, "call_gdbserver called when gdbserver_exited %d\n",
           gdbserver_exited);
      return;
   }

   if (gdbserver_called == 0) {
      vg_assert (gs_addresses == NULL);
      vg_assert (gs_watches == NULL);
      gs_addresses = VG_(HT_construct)( "gdbserved_addresses" );
      gs_watches = VG_(HT_construct)( "gdbserved_watches" );
      VG_(atfork)(NULL, NULL, gdbserver_cleanup_in_child_after_fork);
   }
   vg_assert (gs_addresses != NULL);
   vg_assert (gs_watches != NULL);
   
   gdbserver_called++;

   /* call gdbserver_init if this is the first call to gdbserver. */
   if (gdbserver_called == 1)
      gdbserver_init();

   if (reason == init_reason || gdbserver_called == 1)
      remote_open(VG_(clo_vgdb_prefix));

   /* if the call reason is to initialize, then return control to
      valgrind. After this initialization, gdbserver will be called
      again either if there is an error detected by valgrind or
      if vgdb sends data to the valgrind process. */
   if (reason == init_reason) {
      return;
   }

   stepping = valgrind_single_stepping();

   server_main();

   ignore_this_break_once = valgrind_get_ignore_break_once();
   if (ignore_this_break_once)
      dlog(1, "!!! will ignore_this_break_once %s\n", 
           sym(ignore_this_break_once, /* is_code */ True));
      

   if (valgrind_single_stepping()) {
      /* we are single stepping. If we were not stepping on entry,
         then invalidate the current program counter so as to properly
         do single step. In case the program counter was changed by
         gdb, this will also invalidate the target address we will
         jump to. */
      if (!stepping && tid != 0) {
         invalidate_current_ip (tid, "m_gdbserver single step");
      }
   } else {
      /* We are not single stepping.  If we were stepping on entry,
         then clear the gdbserved addresses.  This will cause all
         these gdbserved blocks to be invalidated so that they can be
         re-translated without being gdbserved. */
      if (stepping)
         clear_gdbserved_addresses(/* clear only jumps */ True);
   }
   
   /* can't do sanity check at beginning. At least the stack
      check is not yet possible. */
   if (gdbserver_called > 1)
      VG_(sanity_check_general) (/* force_expensive */ False);

   /* If the PC has been changed by gdb, then we VG_MINIMAL_LONGJMP to
      the scheduler to execute the block of the new PC.
      Otherwise we just return to continue executing the
      current block. */
   if (VG_(get_IP) (tid) != saved_pc) {
      dlog(1, "tid %d %s PC changed from %s to %s\n",
           tid, VG_(name_of_ThreadStatus) (tst->status),
           sym(saved_pc, /* is_code */ True),
           sym(VG_(get_IP) (tid), /* is_code */ True));
      if (tst->status == VgTs_Yielding) {
         SysRes sres;
         VG_(memset)(&sres, 0, sizeof(SysRes));
         VG_(acquire_BigLock)(tid, "gdbsrv VG_MINIMAL_LONGJMP");
      }
      if (tst->sched_jmpbuf_valid) {
         /* resume scheduler */
         VG_MINIMAL_LONGJMP(tst->sched_jmpbuf);
      }
      /* else continue to run */
   }
   /* continue to run */
}
Exemplo n.º 5
0
static int
amfs_nfsx_init(mntfs *mf)
{
  /*
   * mf_info has the form:
   *   host:/prefix/path,sub,sub,sub
   */
  int i;
  int glob_error;
  struct amfs_nfsx *nx;
  int asked_for_wakeup = 0;

  nx = (struct amfs_nfsx *) mf->mf_private;

  if (nx == 0) {
    char **ivec;
    char *info = 0;
    char *host;
    char *pref;
    int error = 0;

    info = strdup(mf->mf_info);
    host = strchr(info, ':');
    if (!host) {
      error = EINVAL;
      goto errexit;
    }
    pref = host +1;
    host = info;

    /*
     * Split the prefix off from the suffices
     */
    ivec = strsplit(pref, ',', '\'');

    /*
     * Count array size
     */
    for (i = 0; ivec[i]; i++) ;

    nx = ALLOC(struct amfs_nfsx);
    mf->mf_private = (voidp) nx;
    mf->mf_prfree = amfs_nfsx_prfree;

    nx->nx_c = i - 1;		/* i-1 because we don't want the prefix */
    nx->nx_v = (amfs_nfsx_mnt *) xmalloc(nx->nx_c * sizeof(amfs_nfsx_mnt));
    nx->nx_mp = 0;
    {
      char *mp = 0;
      char *xinfo = 0;
      char *fs = mf->mf_fo->opt_fs;
      char *rfs = 0;
      for (i = 0; i < nx->nx_c; i++) {
	char *path = ivec[i + 1];
	rfs = str3cat(rfs, pref, "/", path);
	/*
	 * Determine the mount point.
	 * If this is the root, then don't remove
	 * the trailing slash to avoid mntfs name clashes.
	 */
	mp = str3cat(mp, fs, "/", rfs);
	normalize_slash(mp);
	deslashify(mp);
	/*
	 * Determine the mount info
	 */
	xinfo = str3cat(xinfo, host, *path == '/' ? "" : "/", path);
	normalize_slash(xinfo);
	if (pref[1] != '\0')
	  deslashify(xinfo);
	dlog("amfs_nfsx: init mount for %s on %s", xinfo, mp);
	nx->nx_v[i].n_error = -1;
	nx->nx_v[i].n_mnt = find_mntfs(&nfs_ops, mf->mf_fo, mp, xinfo, "", mf->mf_mopts, mf->mf_remopts);
      }
      if (rfs)
	XFREE(rfs);
      if (mp)
	XFREE(mp);
      if (xinfo)
	XFREE(xinfo);
    }

    XFREE(ivec);
  errexit:
    if (info)
      XFREE(info);
    if (error)
      return error;
  }
Exemplo n.º 6
0
int
destroy_autofs_service(void)
{
    dlog("destroying autofs service listener");
    return unregister_autofs_service(AUTOFS_CONFTYPE);
}
Exemplo n.º 7
0
int main(void){
	int a;
	scanf("%d",&a);
	printf("%f\n",dlog(a));
}
Exemplo n.º 8
0
 ~scope_logger() { dlog("leaving peer_connection::destroy() for peer ${endpoint}", ("endpoint", endpoint)); }
Exemplo n.º 9
0
 scope_logger() { dlog("entering peer_connection::accept_connection()"); }
Exemplo n.º 10
0
int
main(int argc, char *argv[])
{
	char pidstr[16];
	ssize_t ret;
	int c, log_method;
	char *logfile, *pidfile;
	int facility, fd;
	char *username = NULL;
	char *chrootdir = NULL;
	int configtest = 0;
	int singleprocess = 0;
#ifdef HAVE_GETOPT_LONG
	int opt_idx;
#endif

	pname = ((pname=strrchr(argv[0],'/')) != NULL)?pname+1:argv[0];

	srand((unsigned int)time(NULL));

	log_method = L_STDERR_SYSLOG;
	logfile = PATH_RADVD_LOG;
	conf_file = PATH_RADVD_CONF;
	facility = LOG_DAEMON;    //brcm
	pidfile = PATH_RADVD_PID;

	/* parse args */
#define OPTIONS_STR "d:C:l:m:p:t:u:vhcs"
#ifdef HAVE_GETOPT_LONG
	while ((c = getopt_long(argc, argv, OPTIONS_STR, prog_opt, &opt_idx)) > 0)
#else
	while ((c = getopt(argc, argv, OPTIONS_STR)) > 0)
#endif
	{
		switch (c) {
		case 'C':
			conf_file = optarg;
			break;
		case 'd':
			set_debuglevel(atoi(optarg));
			break;
		case 'f':
			facility = atoi(optarg);
			break;
		case 'l':
			logfile = optarg;
			break;
		case 'p':
			pidfile = optarg;
			break;
		case 'm':
			if (!strcmp(optarg, "syslog"))
			{
				log_method = L_SYSLOG;
			}
			else if (!strcmp(optarg, "stderr_syslog"))
			{
				log_method = L_STDERR_SYSLOG;
			}
			else if (!strcmp(optarg, "stderr"))
			{
				log_method = L_STDERR;
			}
			else if (!strcmp(optarg, "logfile"))
			{
				log_method = L_LOGFILE;
			}
			else if (!strcmp(optarg, "none"))
			{
				log_method = L_NONE;
			}
			else
			{
				fprintf(stderr, "%s: unknown log method: %s\n", pname, optarg);
				exit(1);
			}
			break;
		case 't':
			chrootdir = strdup(optarg);
			break;
		case 'u':
			username = strdup(optarg);
			break;
		case 'v':
			version();
			break;
		case 'c':
			configtest = 1;
			break;
		case 's':
			singleprocess = 1;
			break;
		case 'h':
			usage();
#ifdef HAVE_GETOPT_LONG
		case ':':
			fprintf(stderr, "%s: option %s: parameter expected\n", pname,
				prog_opt[opt_idx].name);
			exit(1);
#endif
		case '?':
			exit(1);
		}
	}

	if (chrootdir) {
		if (!username) {
			fprintf(stderr, "Chroot as root is not safe, exiting\n");
			exit(1);
		}

		if (chroot(chrootdir) == -1) {
			perror("chroot");
			exit (1);
		}

		if (chdir("/") == -1) {
			perror("chdir");
			exit (1);
		}
		/* username will be switched later */
	}

	if (configtest) {
		log_method = L_STDERR;
	}

	if (log_open(log_method, pname, logfile, facility) < 0) {
		perror("log_open");
		exit(1);
	}

	if (!configtest) {
		flog(LOG_INFO, "version %s started", "1.8");
	}

	/* get a raw socket for sending and receiving ICMPv6 messages */
	sock = open_icmpv6_socket();
	if (sock < 0) {
		perror("open_icmpv6_socket");
		exit(1);
	}

#ifndef BRCM_CMS_BUILD //brcm
	/* check that 'other' cannot write the file
         * for non-root, also that self/own group can't either
         */
	if (check_conffile_perm(username, conf_file) < 0) {
		if (get_debuglevel() == 0) {
			flog(LOG_ERR, "Exiting, permissions on conf_file invalid.\n");
			exit(1);
		}
		else
			flog(LOG_WARNING, "Insecure file permissions, but continuing anyway");
	}

	/* if we know how to do it, check whether forwarding is enabled */
	if (check_ip6_forwarding()) {
		flog(LOG_WARNING, "IPv6 forwarding seems to be disabled, but continuing anyway.");
	}
#endif

	/* parse config file */
	if (readin_config(conf_file) < 0) {
		flog(LOG_ERR, "Exiting, failed to read config file.\n");
		exit(1);
	}

	if (configtest) {
		fprintf(stderr, "Syntax OK\n");
		exit(0);
	}

	/* drop root privileges if requested. */
	if (username) {
		if (!singleprocess) {
		 	dlog(LOG_DEBUG, 3, "Initializing privsep");
		 	if (privsep_init() < 0)
				flog(LOG_WARNING, "Failed to initialize privsep.");
		}

		if (drop_root_privileges(username) < 0) {
			perror("drop_root_privileges");
			exit(1);
		}
	}

	if ((fd = open(pidfile, O_RDONLY, 0)) > 0)
	{
		ret = read(fd, pidstr, sizeof(pidstr) - 1);
		if (ret < 0)
		{
			flog(LOG_ERR, "cannot read radvd pid file, terminating: %s", strerror(errno));
			exit(1);
		}
		pidstr[ret] = '\0';
		if (!kill((pid_t)atol(pidstr), 0))
		{
			flog(LOG_ERR, "radvd already running, terminating.");
			exit(1);
		}
		close(fd);
		fd = open(pidfile, O_CREAT|O_TRUNC|O_WRONLY, 0644);
	}
	else	/* FIXME: not atomic if pidfile is on an NFS mounted volume */
		fd = open(pidfile, O_CREAT|O_EXCL|O_WRONLY, 0644);

	if (fd < 0)
	{
		flog(LOG_ERR, "cannot create radvd pid file, terminating: %s", strerror(errno));
		exit(1);
	}

	/*
	 * okay, config file is read in, socket and stuff is setup, so
	 * lets fork now...
	 */

#ifndef BRCM_CMS_BUILD //brcm
	if (get_debuglevel() == 0) {

		/* Detach from controlling terminal */
		if (daemon(0, 0) < 0)
			perror("daemon");

		/* close old logfiles, including stderr */
		log_close();

		/* reopen logfiles, but don't log to stderr unless explicitly requested */
		if (log_method == L_STDERR_SYSLOG)
			log_method = L_SYSLOG;
		if (log_open(log_method, pname, logfile, facility) < 0) {
			perror("log_open");
			exit(1);
		}

	}
#endif

	/*
	 *	config signal handlers
	 */
#ifdef BRCM_CMS_BUILD //brcm
	signal(SIGHUP, SIG_IGN);
	signal(SIGTERM, sigterm_handler);
	signal(SIGPIPE, SIG_IGN);
	signal(SIGINT, SIG_IGN);
	signal(SIGUSR1, SIG_IGN);
#else
	signal(SIGHUP, sighup_handler);
	signal(SIGTERM, sigterm_handler);
	signal(SIGINT, sigint_handler);
	signal(SIGUSR1, sigusr1_handler);
#endif

	snprintf(pidstr, sizeof(pidstr), "%ld\n", (long)getpid());

	ret = write(fd, pidstr, strlen(pidstr));
	if (ret != strlen(pidstr))
	{
		flog(LOG_ERR, "cannot write radvd pid file, terminating: %s", strerror(errno));
		exit(1);
	}

	close(fd);

	config_interface();
	kickoff_adverts();
	main_loop();
	stop_adverts();
	unlink(pidfile);

	return 0;
}
Exemplo n.º 11
0
 scope_logger(const fc::optional<fc::ip::endpoint>& endpoint) : endpoint(endpoint) { dlog("entering peer_connection::destroy() for peer ${endpoint}", ("endpoint", endpoint)); }
Exemplo n.º 12
0
void reload_config(void)
{
	struct Interface *iface;

	flog(LOG_INFO, "attempting to reread config file");

	dlog(LOG_DEBUG, 4, "reopening log");
	if (log_reopen() < 0) {
		perror("log_reopen");
		exit(1);
	}

	iface=IfaceList;
	while(iface)
	{
		struct Interface *next_iface = iface->next;
		struct AdvPrefix *prefix;
		struct AdvRoute *route;
		struct AdvRDNSS *rdnss;
		struct AdvDNSSL *dnssl;

		dlog(LOG_DEBUG, 4, "freeing interface %s", iface->Name);

		prefix = iface->AdvPrefixList;
		while (prefix)
		{
			struct AdvPrefix *next_prefix = prefix->next;

			free(prefix);
			prefix = next_prefix;
		}

		route = iface->AdvRouteList;
		while (route)
		{
			struct AdvRoute *next_route = route->next;

			free(route);
			route = next_route;
		}

		rdnss = iface->AdvRDNSSList;
		while (rdnss)
		{
			struct AdvRDNSS *next_rdnss = rdnss->next;

			free(rdnss);
			rdnss = next_rdnss;
		}

		dnssl = iface->AdvDNSSLList;
		while (dnssl)
		{
			struct AdvDNSSL *next_dnssl = dnssl->next;
			int i;

			for (i = 0; i < dnssl->AdvDNSSLNumber; i++)
				free(dnssl->AdvDNSSLSuffixes[i]);
			free(dnssl->AdvDNSSLSuffixes);
			free(dnssl);

			dnssl = next_dnssl;
		}

		free(iface);
		iface = next_iface;
	}

	IfaceList = NULL;

	/* reread config file */
	if (readin_config(conf_file) < 0) {
		perror("readin_config failed.");
		exit(1);
	}

	/* XXX: fails due to lack of permissions with non-root user */
	config_interface();
	kickoff_adverts();

	flog(LOG_INFO, "resuming normal operation");
}
Exemplo n.º 13
0
void main_loop(void)
{
	struct pollfd fds[2];

	memset(fds, 0, sizeof(fds));

	fds[0].fd = sock;
	fds[0].events = POLLIN;
	fds[0].revents = 0;

#if HAVE_NETLINK
	fds[1].fd = netlink_socket();
	fds[1].events = POLLIN;
	fds[1].revents = 0;
#else
	fds[1].fd = -1;
	fds[1].events = 0;
	fds[1].revents = 0;
#endif

	for (;;) {
		struct Interface *next = NULL;
		struct Interface *iface;
		int timeout = -1;
		int rc;

		if (IfaceList) {
			timeout = next_time_msec(IfaceList);
			next = IfaceList;
			for (iface = IfaceList; iface; iface = iface->next) {
				int t;
				t = next_time_msec(iface);
				if (timeout > t) {
					timeout = t;
					next = iface;
				}
			}
		}

		dlog(LOG_DEBUG, 3, "polling for %g seconds.", timeout/1000.0);

		rc = poll(fds, sizeof(fds)/sizeof(fds[0]), timeout);

		if (rc > 0) {
			if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
				flog(LOG_WARNING, "socket error on fds[0].fd");
			}
			else if (fds[0].revents & POLLIN) {
				int len, hoplimit;
				struct sockaddr_in6 rcv_addr;
				struct in6_pktinfo *pkt_info = NULL;
				unsigned char msg[MSG_SIZE_RECV];

				len = recv_rs_ra(msg, &rcv_addr, &pkt_info, &hoplimit);
				if (len > 0) {
					process(IfaceList, msg, len,
						&rcv_addr, pkt_info, hoplimit);
				}
			}
#ifdef HAVE_NETLINK
			if (fds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) {
				flog(LOG_WARNING, "socket error on fds[1].fd");
			}
			else if (fds[1].revents & POLLIN) {
				process_netlink_msg(fds[1].fd);
			}
#endif
		}
		else if ( rc == 0 ) {
			if (next)
				timer_handler(next);
		}
		else if ( rc == -1 ) {
			flog(LOG_WARNING, "poll error: %s", strerror(errno));
		}

		//brcm
		if (sigterm_received) {
			flog(LOG_WARNING, "Exiting, sigterm received.\n");
			break;
		}

		if (sighup_received)
		{
			reload_config();
			sighup_received = 0;
		}

		if (sigusr1_received)
		{
			reset_prefix_lifetimes();
			sigusr1_received = 0;
		}

	}
}
Exemplo n.º 14
0
/* <dposnum> <dresult> .dlog <dresult> */
static int
zdlog(i_ctx_t *i_ctx_p)
{
    return dlog(i_ctx_p, log10);
}
Exemplo n.º 15
0
static void connection_remove(struct connection *conn)
{
	dlog(LOG_LEVEL, "Remove connection.\n");
	closesocket(conn->sockfd);
	free(conn);
}
Exemplo n.º 16
0
 ~scope_logger() { dlog("leaving peer_connection::accept_connection()"); }
Exemplo n.º 17
0
/*
 * Create the autofs service for amd
 */
int
create_autofs_service(void)
{
    dlog("creating autofs service listener");
    return register_autofs_service(AUTOFS_CONFTYPE, autofs_program_1);
}
Exemplo n.º 18
0
    void peer_connection::destroy()
    {
      VERIFY_CORRECT_THREAD();

#if 0 // this gets too verbose
#ifndef NDEBUG
      struct scope_logger {
        fc::optional<fc::ip::endpoint> endpoint;
        scope_logger(const fc::optional<fc::ip::endpoint>& endpoint) : endpoint(endpoint) { dlog("entering peer_connection::destroy() for peer ${endpoint}", ("endpoint", endpoint)); }
        ~scope_logger() { dlog("leaving peer_connection::destroy() for peer ${endpoint}", ("endpoint", endpoint)); }
      } send_message_scope_logger(get_remote_endpoint());
#endif
#endif

      try
      {
        dlog("calling close_connection()");
        close_connection();
        dlog("close_connection completed normally");
      }
      catch ( const fc::canceled_exception& )
      {
        assert(false && "the task that deletes peers should not be canceled because it will prevent us from cleaning up correctly");
      }
      catch ( ... )
      {
        dlog("close_connection threw");
      }

      try
      {
        dlog("canceling _send_queued_messages task");
        _send_queued_messages_done.cancel_and_wait(__FUNCTION__);
        dlog("cancel_and_wait completed normally");
      }
      catch( const fc::exception& e )
      {
        wlog("Unexpected exception from peer_connection's send_queued_messages_task : ${e}", ("e", e));
      }
      catch( ... )
      {
        wlog("Unexpected exception from peer_connection's send_queued_messages_task");
      }

      try
      {
        dlog("canceling accept_or_connect_task");
        accept_or_connect_task_done.cancel_and_wait(__FUNCTION__);
        dlog("accept_or_connect_task completed normally");
      }
      catch( const fc::exception& e )
      {
        wlog("Unexpected exception from peer_connection's accept_or_connect_task : ${e}", ("e", e));
      }
      catch( ... )
      {
        wlog("Unexpected exception from peer_connection's accept_or_connect_task");
      }

      _message_connection.destroy_connection(); // shut down the read loop
    }
Exemplo n.º 19
0
int main(int argc, char *argv[])
{
	int ret, i, action = -1;
	char config_file[PATH_MAX] = {};
	int type = 0;
	struct utsname u;
	int version, major, minor;

	/* Check kernel version: it must be >= 2.6.18 */
	if (uname(&u) == -1) {
		dlog(LOG_ERR, "Can't retrieve kernel version via uname()");
		exit(EXIT_FAILURE);
	}
	sscanf(u.release, "%d.%d.%d", &version, &major, &minor);
	if (version < 2 && major < 6 && minor < 18) {
		dlog(LOG_ERR, "Linux kernel version must be >= 2.6.18");
		exit(EXIT_FAILURE);
	}

	for (i=1; i<argc; i++) {
		switch(argv[i][1]) {
		case 'd':
			set_operation_mode(&type, DAEMON, argv);
			CONFIG(running_mode) = DAEMON;
			break;
		case 'c':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_COMMIT, EXP_COMMIT,
						ALL_COMMIT, &action);
			break;
		case 'i':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_DUMP_INTERNAL,
						EXP_DUMP_INTERNAL,
						CT_DUMP_INTERNAL, &action);
			break;
		case 'e':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_DUMP_EXTERNAL,
						EXP_DUMP_EXTERNAL,
						CT_DUMP_EXTERNAL, &action);
			break;
		case 'C':
			if (++i < argc) {
				strncpy(config_file, argv[i], PATH_MAX);
				if (strlen(argv[i]) >= PATH_MAX){
					config_file[PATH_MAX-1]='\0';
					dlog(LOG_WARNING, "Path to config file"
					     " to long. Cutting it down to %d"
					     " characters", PATH_MAX);
				}
				break;
			}
			show_usage(argv[0]);
			dlog(LOG_ERR, "Missing config filename");
			break;
		case 'F':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_FLUSH_MASTER,
						EXP_FLUSH_MASTER,
						ALL_FLUSH_MASTER, &action);
			break;
		case 'f':
			set_operation_mode(&type, REQUEST, argv);
			if (i+1 < argc && argv[i+1][0] != '-') {
				if (strncmp(argv[i+1], "internal",
					    strlen(argv[i+1])) == 0) {
					action = CT_FLUSH_INT_CACHE;
					i++;
				} else if (strncmp(argv[i+1], "external",
						 strlen(argv[i+1])) == 0) {
					action = CT_FLUSH_EXT_CACHE;
					i++;
				} else {
					dlog(LOG_ERR, "unknown parameter `%s' "
					     "for option `-f'", argv[i + 1]);
					exit(EXIT_FAILURE);
				}
			} else {
				/* default to general flushing */
				action = ALL_FLUSH_CACHE;
			}
			break;
		case 'R':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_RESYNC_MASTER,
						EXP_RESYNC_MASTER,
						ALL_RESYNC_MASTER, &action);
			break;
		case 'B':
			set_operation_mode(&type, REQUEST, argv);
			action = SEND_BULK;
			break;
		case 't':
			set_operation_mode(&type, REQUEST, argv);
			action = RESET_TIMERS;
			break;
		case 'k':
			set_operation_mode(&type, REQUEST, argv);
			action = KILL;
			break;
		case 's':
			set_operation_mode(&type, REQUEST, argv);
			/* we've got a parameter */
			if (i+1 < argc && argv[i+1][0] != '-') {
				if (strncmp(argv[i+1], "network",
					    strlen(argv[i+1])) == 0) {
					action = STATS_NETWORK;
					i++;
				} else if (strncmp(argv[i+1], "cache",
						 strlen(argv[i+1])) == 0) {
					action = STATS_CACHE;
					i++;
				} else if (strncmp(argv[i+1], "runtime",
						 strlen(argv[i+1])) == 0) {
					action = STATS_RUNTIME;
					i++;
				} else if (strncmp(argv[i+1], "multicast",
						 strlen(argv[i+1])) == 0) {
					dlog(LOG_WARNING, "use `link' "
					     "instead of `multicast' as "
					     "parameter.");
					action = STATS_LINK;
					i++;
				} else if (strncmp(argv[i+1], "link",
						 strlen(argv[i+1])) == 0) {
					action = STATS_LINK;
					i++;
				} else if (strncmp(argv[i+1], "rsqueue",
						strlen(argv[i+1])) == 0) {
					action = STATS_RSQUEUE;
					i++;
				} else if (strncmp(argv[i+1], "process",
						 strlen(argv[i+1])) == 0) {
					action = STATS_PROCESS;
					i++;
				} else if (strncmp(argv[i+1], "queue",
						strlen(argv[i+1])) == 0) {
					action = STATS_QUEUE;
					i++;
				} else if (strncmp(argv[i+1], "ct",
						strlen(argv[i+1])) == 0) {
					action = STATS;
					i++;
				} else if (strncmp(argv[i+1], "expect",
						strlen(argv[i+1])) == 0) {
					action = EXP_STATS;
					i++;
				} else {
					dlog(LOG_ERR, "unknown parameter `%s' "
					     "for option `-s'", argv[i + 1]);
					exit(EXIT_FAILURE);
				}
			} else {
				/* default to general statistics */
				action = STATS;
			}
			break;
		case 'S':
			dlog(LOG_WARNING,"-S option is obsolete. Ignoring.");
			break;
		case 'n':
			set_operation_mode(&type, REQUEST, argv);
			action = REQUEST_DUMP;
			break;
		case 'x':
			if (action == CT_DUMP_INTERNAL)
				action = CT_DUMP_INT_XML;
			else if (action == CT_DUMP_EXTERNAL)
				action = CT_DUMP_EXT_XML;
			else if (action == EXP_DUMP_INTERNAL)
				action = EXP_DUMP_INT_XML;
			else if (action == EXP_DUMP_EXTERNAL)
				action = EXP_DUMP_EXT_XML;
			else {
				show_usage(argv[0]);
				dlog(LOG_ERR,  "Invalid parameters");
				exit(EXIT_FAILURE);

			}
			break;
		case 'v':
			show_version();
			exit(EXIT_SUCCESS);
		case 'h':
			show_usage(argv[0]);
			exit(EXIT_SUCCESS);
		default:
			show_usage(argv[0]);
			dlog(LOG_ERR, "Unknown option: %s", argv[i]);
			return 0;
			break;
		}
	}

	if (!config_file[0])
		strcpy(config_file, DEFAULT_CONFIGFILE);

	umask(0177);

	if ((ret = init_config(config_file)) == -1) {
		dlog(LOG_ERR, "can't open config file `%s'", config_file);
		exit(EXIT_FAILURE);
	}

	if (type == REQUEST) {
		if (do_local_request(action, &conf.local, local_step) == -1) {
			dlog(LOG_ERR, "can't connect: is conntrackd "
			     "running? appropriate permissions?");
			exit(EXIT_FAILURE);
		}
		exit(EXIT_SUCCESS);
	}

	/*
	 * Setting up logging
	 */
	if (init_log() == -1)
		exit(EXIT_FAILURE);

	/*
	 * lock file
	 */
	ret = open(CONFIG(lockfile), O_CREAT | O_EXCL | O_TRUNC, 0600);
	if (ret == -1) {
		dlog(LOG_ERR, "lockfile `%s' exists, perhaps conntrackd"
		     " already running?", CONFIG(lockfile));
		exit(EXIT_FAILURE);
	}
	close(ret);

	/*
	 * Setting process priority and scheduler
	 */
	set_nice_value(CONFIG(nice));

	if (CONFIG(sched).type != SCHED_OTHER) {
		struct sched_param schedparam = {
			.sched_priority = CONFIG(sched).prio,
		};

		ret = sched_setscheduler(0, CONFIG(sched).type, &schedparam);
		if (ret == -1) {
			dlog(LOG_ERR, "scheduler configuration failed: %s",
			     strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	/*
	 * initialization process
	 */

	if (init() == -1) {
		dlog(LOG_ERR, "conntrackd cannot start, please review your "
		     "configuration");
		close_log();
		unlink(CONFIG(lockfile));
		exit(EXIT_FAILURE);
	}

	do_chdir("/");
	close(STDIN_FILENO);

	sd_ct_watchdog_init();

	/* Daemonize conntrackd */
	if (type == DAEMON) {
		pid_t pid;

		if ((pid = fork()) == -1) {
			dlog(LOG_ERR, "fork has failed: %s", strerror(errno));
			exit(EXIT_FAILURE);
		} else if (pid) {
			sd_ct_mainpid(pid);
			exit(EXIT_SUCCESS);
		}

		setsid();

		close(STDOUT_FILENO);
		close(STDERR_FILENO);

		dlog(LOG_NOTICE, "-- starting in daemon mode --");
	} else
		dlog(LOG_NOTICE, "-- starting in console mode --");

	sd_ct_init();

	/*
	 * run main process
	 */
	select_main_loop();
	return 0;
}
Exemplo n.º 20
0
static void
setupTerminal(void)
{
    int _stdin, _stdout, _stderr;
    boolean_t ctty = B_FALSE;
    char *data;
    boolean_t open_stdin = getStdinStatus();

    if ((data = mdataGet("docker:tty")) != NULL) {
        if (strcmp("true", data) == 0) {
            ctty = B_TRUE;
        }
        free(data);
    }

    dlog("SWITCHING TO /dev/zfd/*\n");

    /*
     * If 'OpenStdin' is set on the container we reopen stdin as connected to
     * the zfd. Otherwise we leave it opened as /dev/null.
     */
    if (open_stdin) {
        if (close(0) == -1) {
            fatal(ERR_CLOSE, "failed to close(0): %s\n", strerror(errno));
        }

        _stdin = open("/dev/zfd/0", O_RDWR);
        if (_stdin == -1) {
            if (errno == ENOENT) {
                _stdin = open("/dev/null", O_RDONLY);
                if (_stdin == -1) {
                    fatal(ERR_OPEN_CONSOLE, "failed to open /dev/null: %s\n",
                        strerror(errno));
                }
            } else {
                fatal(ERR_OPEN_CONSOLE, "failed to open /dev/zfd/0: %s\n",
                    strerror(errno));
            }
        }
    }

    if (close(1) == -1) {
        fatal(ERR_CLOSE, "failed to close(1): %s\n", strerror(errno));
    }
    if (close(2) == -1) {
        fatal(ERR_CLOSE, "failed to close(2): %s\n", strerror(errno));
    }

    if (ctty) {
        /* Configure output as a controlling terminal */
        _stdout = open("/dev/zfd/0", O_WRONLY);
        if (_stdout == -1) {
            fatal(ERR_OPEN_CONSOLE, "failed to open /dev/zfd/0: %s\n",
                strerror(errno));
        }
        _stderr = open("/dev/zfd/0", O_WRONLY);
        if (_stderr == -1) {
            fatal(ERR_OPEN_CONSOLE, "failed to open /dev/zfd/0: %s\n",
                strerror(errno));
        }

        if (setsid() < 0) {
            fatal(ERR_OPEN_CONSOLE, "failed to create process session: %s\n",
                strerror(errno));
        }
        if (ioctl(_stdout, TIOCSCTTY, NULL) < 0) {
            fatal(ERR_OPEN_CONSOLE, "failed set controlling tty: %s\n",
                strerror(errno));
        }
    } else {
        /* Configure individual pipe style output */
        _stdout = open("/dev/zfd/1", O_WRONLY);
        if (_stdout == -1) {
            fatal(ERR_OPEN_CONSOLE, "failed to open /dev/zfd/1: %s\n",
                strerror(errno));
        }
        _stderr = open("/dev/zfd/2", O_WRONLY);
        if (_stderr == -1) {
            fatal(ERR_OPEN_CONSOLE, "failed to open /dev/zfd/2: %s\n",
                strerror(errno));
        }
    }
}
Exemplo n.º 21
0
Bool VG_(is_watched)(PointKind kind, Addr addr, Int szB)
{
   GS_Watch* g;
   Bool watched = False;
   const ThreadId tid = VG_(running_tid);

   if (!gdbserver_called)
      return False;

   Addr to = addr + szB; // semi-open interval [addr, to[

   vg_assert (kind == access_watchpoint 
              || kind == read_watchpoint 
              || kind == write_watchpoint);
   dlog(1, "tid %d VG_(is_watched) %s addr %p szB %d\n",
        tid, VG_(ppPointKind) (kind), C2v(addr), szB);
   VG_(HT_ResetIter) (gs_watches);
   while ((g = VG_(HT_Next) (gs_watches))) {
      switch (g->kind) {
      case software_breakpoint:
      case hardware_breakpoint:
         break;
      case access_watchpoint:
      case read_watchpoint:
      case write_watchpoint:
         if (to <= g->addr || addr >= (g->addr + g->len))
            /* If no overlap, examine next watchpoint: */
            continue;

         watched = True; /* We have an overlap */

         /* call gdbserver if access kind reported by the tool
            matches the watchpoint kind. */
         if (kind == access_watchpoint
             || g->kind == access_watchpoint
             || g->kind == kind) {
            /* Watchpoint encountered.
               If this is a read watchpoint, we directly call gdbserver
               to report it to gdb.
               Otherwise, for a write watchpoint, we have to finish
               the instruction so as to modify the value.
               If we do not finish the instruction, then gdb sees no
               value change and continues.
               For a read watchpoint, we better call gdbserver directly:
               in case the current block is not gdbserved, Valgrind
               will execute instructions till the next block. */

            /* set the watchpoint stop address to the first read or written. */
            if (g->addr <= addr) {
               VG_(set_watchpoint_stop_address) (addr);
            } else {
               VG_(set_watchpoint_stop_address) (g->addr);
            }

            if (kind == write_watchpoint) {
               /* Let Valgrind stop as early as possible after this instruction
                  by switching to Single Stepping mode. */
               valgrind_set_single_stepping (True);
               invalidate_current_ip (tid, "m_gdbserver write watchpoint");
            } else {
               call_gdbserver (tid, watch_reason);
               VG_(set_watchpoint_stop_address) ((Addr) 0);
            }
            return True; // we are watched here.
         }
         break;
      default:
         vg_assert (0);
      }
   }
   return watched;
}
Exemplo n.º 22
0
int
addRoute(const char *ifname, const char *gw, const char *dst, int dstpfx)
{
    int idx;
    int len;
    char rtbuf[RTMBUFSZ];
    struct rt_msghdr *rtm = (struct rt_msghdr *)rtbuf;
    int sockfd;
    struct sockaddr_in *dst_sin = (struct sockaddr_in *)
        (rtbuf + sizeof (struct rt_msghdr));
    struct sockaddr_in *gw_sin = (struct sockaddr_in *) (dst_sin + 1);
    struct sockaddr_in *netmask_sin = (struct sockaddr_in *) (gw_sin + 1);

    dlog("ROUTE[%s] gw=%s, dst=%s\n", ifname, gw, dst);

    (void) bzero(rtm, RTMBUFSZ);
    rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
    rtm->rtm_flags = RTF_UP | RTF_STATIC | RTF_GATEWAY;
    rtm->rtm_msglen = sizeof (rtbuf);
    rtm->rtm_pid = getpid();
    rtm->rtm_type = RTM_ADD;
    rtm->rtm_version = RTM_VERSION;

    dst_sin->sin_family = AF_INET;
    if ((inet_pton(AF_INET, dst, &(dst_sin->sin_addr))) != 1) {
        dlog(ROUTE_ADDR_MSG, "destination", dst, ifname, strerror(errno));
        return (-1);
    }

    dst_sin->sin_family = AF_INET;
    if ((inet_pton(AF_INET, gw, &(gw_sin->sin_addr))) != 1) {
        dlog(ROUTE_ADDR_MSG, "gateway", gw, ifname, strerror(errno));
        return (-2);
    }

    netmask_sin->sin_family = AF_INET;
    if (prefixToNetmask(dstpfx, netmask_sin) != 0) {
        WARNLOG("invalid route prefix length %d", dstpfx);
        return (-3);
    }

    if (ifname != NULL) {
        if ((idx = if_nametoindex(ifname)) == 0) {
            dlog("WARN addRoute: error getting interface index for %s: %s\n",
                ifname, strerror(errno));
            return (-4);
        }
        rtm->rtm_index = idx;
    }

    if ((sockfd = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
        dlog("WARN addRoute: error opening socket: %s\n", strerror(errno));
        return (-5);
    }

    if ((len = write(sockfd, rtbuf, rtm->rtm_msglen)) < 0) {
        dlog(ROUTE_WRITE_ERR_MSG, ifname, gw, dst, strerror(errno));
        close(sockfd);
        return (-6);
    }

    if (len < rtm->rtm_msglen) {
        dlog(ROUTE_WRITE_LEN_MSG, len, rtm->rtm_msglen, ifname, gw, dst,
            strerror(errno));
        close(sockfd);
        return (-7);
    }

    close(sockfd);
    return (0);
}
Exemplo n.º 23
0
/* Using ptrace calls, vgdb will force an invocation of gdbserver.
   VG_(invoke_gdbserver) is the entry point called through the
   vgdb ptrace technique. */
void VG_(invoke_gdbserver) ( int check )
{
   /* ******* Avoid non-reentrant function call from here ..... 
      till the ".... till here" below. */

   /* We need to determine the state of the various threads to decide
      if we directly invoke gdbserver or if we rather indicate to the
      scheduler to invoke the gdbserver.  To decide that, it is
      critical to avoid any "coregrind" function call as the ptrace
      might have stopped the process in the middle of this (possibly)
      non-rentrant function.  So, it is only when all threads are in
      an "interruptible" state that we can safely invoke
      gdbserver. Otherwise, we let the valgrind scheduler invoke
      gdbserver at the next poll.  This poll will be made very soon
      thanks to a call to VG_(force_vgdb_poll). */
   int n_tid;

   vg_assert (check == 0x8BADF00D);

   if (busy) {
      interrupts_while_busy++;
      give_control_back_to_vgdb();
   }
   interrupts_non_busy++;

   /* check if all threads are in an "interruptible" state.  If yes,
      we invoke gdbserver. Otherwise, we tell the scheduler to wake up
      asap. */
   for (n_tid = 1; n_tid < VG_N_THREADS; n_tid++) {
      switch (VG_(threads)[n_tid].status) {
      /* interruptible states. */
      case VgTs_WaitSys:
      case VgTs_Yielding:
         if (vgdb_interrupted_tid == 0) vgdb_interrupted_tid = n_tid;
         break;

      case VgTs_Empty:     
      case VgTs_Zombie:
         break;

      /* non interruptible states. */
      case VgTs_Init:
      case VgTs_Runnable:
         interrupts_non_interruptible++;
         VG_(force_vgdb_poll) ();
         give_control_back_to_vgdb();

      default:             vg_assert(0);
      }
   }

   /* .... till here.
      From here onwards, function calls are ok: it is
      safe to call valgrind core functions: all threads are blocked in
      a system call or are yielding or ... */
   dlog(1, "invoke_gdbserver running_tid %d vgdb_interrupted_tid %d\n",
        VG_(running_tid), vgdb_interrupted_tid);
   call_gdbserver (vgdb_interrupted_tid, vgdb_reason);
   vgdb_interrupted_tid = 0;
   dlog(1,
        "exit invoke_gdbserver running_tid %d\n", VG_(running_tid));
   give_control_back_to_vgdb();

   vg_assert2(0, "end of invoke_gdbserver reached");

}
Exemplo n.º 24
0
Arquivo: send.c Projeto: gygy/asuswrt
int send_ra(struct Interface *iface, struct in6_addr *dest)
{
	uint8_t all_hosts_addr[] = { 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
	struct nd_router_advert *radvert;
	struct AdvPrefix *prefix;
	struct AdvRoute *route;
	struct AdvRDNSS *rdnss;
	struct AdvDNSSL *dnssl;
	struct AdvLowpanCo *lowpanco;
	struct AdvAbro *abroo;
	struct timespec time_now;
	int64_t secs_since_last_ra;
	char addr_str[INET6_ADDRSTRLEN];

	unsigned char buff[MSG_SIZE_SEND];
	size_t buff_dest = 0;
	size_t len = 0;
	ssize_t err;

	update_device_info(iface);

	/* First we need to check that the interface hasn't been removed or deactivated */
	if (check_device(iface) < 0) {
		if (iface->IgnoreIfMissing)	/* a bit more quiet warning message.. */
			dlog(LOG_DEBUG, 4, "interface %s does not exist, ignoring the interface", iface->Name);
		else {
			flog(LOG_WARNING, "interface %s does not exist, ignoring the interface", iface->Name);
		}
		iface->HasFailed = 1;
		/* not really a 'success', but we need to schedule new timers.. */
		return 0;
	} else {
		/* check_device was successful, act if it has failed previously */
		if (iface->HasFailed == 1) {
			flog(LOG_WARNING, "interface %s seems to have come back up, trying to reinitialize", iface->Name);
			iface->HasFailed = 0;
			/*
			 * return -1 so timer_handler() doesn't schedule new timers,
			 * reload_config() will kick off new timers anyway.  This avoids
			 * timer list corruption.
			 */
			reload_config();
			return -1;
		}
	}

	/* Make sure that we've joined the all-routers multicast group */
	if (!disableigmp6check && check_allrouters_membership(iface) < 0)
		flog(LOG_WARNING, "problem checking all-routers membership on %s", iface->Name);

	if (!iface->AdvSendAdvert) {
		dlog(LOG_DEBUG, 2, "AdvSendAdvert is off for %s", iface->Name);
		return 0;
	}

	dlog(LOG_DEBUG, 3, "sending RA on %s", iface->Name);

	if (dest == NULL) {
		dest = (struct in6_addr *)all_hosts_addr;
		clock_gettime(CLOCK_MONOTONIC, &iface->last_multicast);
	}

	clock_gettime(CLOCK_MONOTONIC, &time_now);
	secs_since_last_ra = timespecdiff(&time_now, &iface->last_ra_time) / 1000;
	if (secs_since_last_ra < 0) {
		secs_since_last_ra = 0;
		flog(LOG_WARNING, "clock_gettime(CLOCK_MONOTONIC) went backwards!");
	}
	iface->last_ra_time = time_now;

	memset(buff, 0, sizeof(buff));
	radvert = (struct nd_router_advert *)buff;

	send_ra_inc_len(&len, sizeof(struct nd_router_advert));

	radvert->nd_ra_type = ND_ROUTER_ADVERT;
	radvert->nd_ra_code = 0;
	radvert->nd_ra_cksum = 0;

	radvert->nd_ra_curhoplimit = iface->AdvCurHopLimit;
	radvert->nd_ra_flags_reserved = (iface->AdvManagedFlag) ? ND_RA_FLAG_MANAGED : 0;
	radvert->nd_ra_flags_reserved |= (iface->AdvOtherConfigFlag) ? ND_RA_FLAG_OTHER : 0;
	/* Mobile IPv6 ext */
	radvert->nd_ra_flags_reserved |= (iface->AdvHomeAgentFlag) ? ND_RA_FLAG_HOME_AGENT : 0;

	if (iface->cease_adv) {
		radvert->nd_ra_router_lifetime = 0;
	} else {
		/* if forwarding is disabled, send zero router lifetime */
		radvert->nd_ra_router_lifetime = !check_ip6_forwarding()? htons(iface->AdvDefaultLifetime) : 0;
	}
	radvert->nd_ra_flags_reserved |= (iface->AdvDefaultPreference << ND_OPT_RI_PRF_SHIFT) & ND_OPT_RI_PRF_MASK;

	radvert->nd_ra_reachable = htonl(iface->AdvReachableTime);
	radvert->nd_ra_retransmit = htonl(iface->AdvRetransTimer);

	prefix = iface->AdvPrefixList;

	/*
	 *      add prefix options
	 */

	while (prefix) {
		if (prefix->enabled && (!prefix->DecrementLifetimesFlag || prefix->curr_preferredlft > 0)) {
			struct nd_opt_prefix_info *pinfo;

			pinfo = (struct nd_opt_prefix_info *)(buff + len);

			send_ra_inc_len(&len, sizeof(*pinfo));

			pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
			pinfo->nd_opt_pi_len = 4;
			pinfo->nd_opt_pi_prefix_len = prefix->PrefixLen;

			pinfo->nd_opt_pi_flags_reserved = (prefix->AdvOnLinkFlag) ? ND_OPT_PI_FLAG_ONLINK : 0;
			pinfo->nd_opt_pi_flags_reserved |= (prefix->AdvAutonomousFlag) ? ND_OPT_PI_FLAG_AUTO : 0;
			/* Mobile IPv6 ext */
			pinfo->nd_opt_pi_flags_reserved |= (prefix->AdvRouterAddr) ? ND_OPT_PI_FLAG_RADDR : 0;

			if (iface->cease_adv && prefix->DeprecatePrefixFlag) {
				/* RFC4862, 5.5.3, step e) */
				pinfo->nd_opt_pi_valid_time = htonl(MIN_AdvValidLifetime);
				pinfo->nd_opt_pi_preferred_time = 0;
			} else {
				if (prefix->DecrementLifetimesFlag) {
					decrement_lifetime(secs_since_last_ra, &prefix->curr_validlft);

					decrement_lifetime(secs_since_last_ra, &prefix->curr_preferredlft);
					if (prefix->curr_preferredlft == 0)
						cease_adv_pfx_msg(iface->Name, &prefix->Prefix, prefix->PrefixLen);
				}
				pinfo->nd_opt_pi_valid_time = htonl(prefix->curr_validlft);
				pinfo->nd_opt_pi_preferred_time = htonl(prefix->curr_preferredlft);

			}
			pinfo->nd_opt_pi_reserved2 = 0;

			memcpy(&pinfo->nd_opt_pi_prefix, &prefix->Prefix, sizeof(struct in6_addr));
			print_addr(&prefix->Prefix, addr_str);
			dlog(LOG_DEBUG, 5, "adding prefix %s to advert for %s with %u seconds(s) valid lifetime and %u seconds(s) preferred time",
				addr_str, iface->Name, ntohl(pinfo->nd_opt_pi_valid_time), ntohl(pinfo->nd_opt_pi_preferred_time));
		}

		prefix = prefix->next;
	}

	route = iface->AdvRouteList;

	/*
	 *      add route options
	 */

	while (route) {
		struct nd_opt_route_info_local *rinfo;

		rinfo = (struct nd_opt_route_info_local *)(buff + len);

		send_ra_inc_len(&len, sizeof(*rinfo));

		rinfo->nd_opt_ri_type = ND_OPT_ROUTE_INFORMATION;
		/* XXX: the prefixes are allowed to be sent in smaller chunks as well */
		rinfo->nd_opt_ri_len = 3;
		rinfo->nd_opt_ri_prefix_len = route->PrefixLen;

		rinfo->nd_opt_ri_flags_reserved = (route->AdvRoutePreference << ND_OPT_RI_PRF_SHIFT) & ND_OPT_RI_PRF_MASK;
		if (iface->cease_adv && route->RemoveRouteFlag) {
			rinfo->nd_opt_ri_lifetime = 0;
		} else {
			rinfo->nd_opt_ri_lifetime = htonl(route->AdvRouteLifetime);
		}

		memcpy(&rinfo->nd_opt_ri_prefix, &route->Prefix, sizeof(struct in6_addr));

		route = route->next;
	}

	rdnss = iface->AdvRDNSSList;

	/*
	 *      add rdnss options
	 */

	while (rdnss) {
		struct nd_opt_rdnss_info_local *rdnssinfo;

		rdnssinfo = (struct nd_opt_rdnss_info_local *)(buff + len);

		send_ra_inc_len(&len, sizeof(*rdnssinfo) - (3 - rdnss->AdvRDNSSNumber) * sizeof(struct in6_addr));

		rdnssinfo->nd_opt_rdnssi_type = ND_OPT_RDNSS_INFORMATION;
		rdnssinfo->nd_opt_rdnssi_len = 1 + 2 * rdnss->AdvRDNSSNumber;
		rdnssinfo->nd_opt_rdnssi_pref_flag_reserved = 0;

		if (iface->cease_adv && rdnss->FlushRDNSSFlag) {
			rdnssinfo->nd_opt_rdnssi_lifetime = 0;
		} else {
			rdnssinfo->nd_opt_rdnssi_lifetime = htonl(rdnss->AdvRDNSSLifetime);
		}

		memcpy(&rdnssinfo->nd_opt_rdnssi_addr1, &rdnss->AdvRDNSSAddr1, sizeof(struct in6_addr));
		memcpy(&rdnssinfo->nd_opt_rdnssi_addr2, &rdnss->AdvRDNSSAddr2, sizeof(struct in6_addr));
		memcpy(&rdnssinfo->nd_opt_rdnssi_addr3, &rdnss->AdvRDNSSAddr3, sizeof(struct in6_addr));

		rdnss = rdnss->next;
	}

	dnssl = iface->AdvDNSSLList;

	/*
	 *      add dnssl options
	 */

	while (dnssl) {
		struct nd_opt_dnssl_info_local *dnsslinfo;
		int const start_len = len;
		int i;

		dnsslinfo = (struct nd_opt_dnssl_info_local *)(buff + len);

		send_ra_inc_len(&len, sizeof(dnsslinfo->nd_opt_dnssli_type) +
				sizeof(dnsslinfo->nd_opt_dnssli_len) + sizeof(dnsslinfo->nd_opt_dnssli_reserved) + sizeof(dnsslinfo->nd_opt_dnssli_lifetime)
		    );

		dnsslinfo->nd_opt_dnssli_type = ND_OPT_DNSSL_INFORMATION;
		dnsslinfo->nd_opt_dnssli_reserved = 0;

		if (iface->cease_adv && dnssl->FlushDNSSLFlag) {
			dnsslinfo->nd_opt_dnssli_lifetime = 0;
		} else {
			dnsslinfo->nd_opt_dnssli_lifetime = htonl(dnssl->AdvDNSSLLifetime);
		}

		for (i = 0; i < dnssl->AdvDNSSLNumber; i++) {
			char *label;
			int label_len;

			label = dnssl->AdvDNSSLSuffixes[i];

			while (label[0] != '\0') {
				if (strchr(label, '.') == NULL)
					label_len = strlen(label);
				else
					label_len = strchr(label, '.') - label;

				buff_dest = len;
				send_ra_inc_len(&len, 1);
				buff[buff_dest] = label_len;

				buff_dest = len;
				send_ra_inc_len(&len, label_len);
				memcpy(buff + buff_dest, label, label_len);

				label += label_len;

				if (label[0] == '.')
					label++;
				if (label[0] == '\0') {
					buff_dest = len;
					send_ra_inc_len(&len, 1);
					buff[buff_dest] = 0;
				}
			}
		}

		dnsslinfo->nd_opt_dnssli_len = (len - start_len) / 8;

		if ((len - start_len) % 8 != 0) {
			send_ra_inc_len(&len, 8 - (len - start_len) % 8);
			++dnsslinfo->nd_opt_dnssli_len;
		}

		dnssl = dnssl->next;
	}

	/*
	 *      add MTU option
	 */

	if (iface->AdvLinkMTU != 0) {
		struct nd_opt_mtu *mtu;

		mtu = (struct nd_opt_mtu *)(buff + len);

		send_ra_inc_len(&len, sizeof(*mtu));

		mtu->nd_opt_mtu_type = ND_OPT_MTU;
		mtu->nd_opt_mtu_len = 1;
		mtu->nd_opt_mtu_reserved = 0;
		mtu->nd_opt_mtu_mtu = htonl(iface->AdvLinkMTU);
	}

	/*
	 * add Source Link-layer Address option
	 */

	if (iface->AdvSourceLLAddress && iface->if_hwaddr_len > 0) {
		/*
		4.6.1.  Source/Target Link-layer Address

		      0                   1                   2                   3
		      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
		     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		     |     Type      |    Length     |    Link-Layer Address ...
		     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

		   Fields:

		      Type
				     1 for Source Link-layer Address
				     2 for Target Link-layer Address

		      Length         The length of the option (including the type and
				     length fields) in units of 8 octets.  For example,
				     the length for IEEE 802 addresses is 1 [IPv6-
				     ETHER].

		      Link-Layer Address
				     The variable length link-layer address.

				     The content and format of this field (including
				     byte and bit ordering) is expected to be specified
				     in specific documents that describe how IPv6
				     operates over different link layers.  For instance,
				     [IPv6-ETHER].

		*/
		/* +2 for the ND_OPT_SOURCE_LINKADDR and the length (each occupy one byte) */
		size_t const sllao_bytes = (iface->if_hwaddr_len / 8) + 2;
		size_t const sllao_len = (sllao_bytes + 7) / 8;
		uint8_t *sllao = (uint8_t *) (buff + len);

		send_ra_inc_len(&len, sllao_len * 8);

		*sllao++ = ND_OPT_SOURCE_LINKADDR;
		*sllao++ = (uint8_t) sllao_len;

		/* if_hwaddr_len is in bits, so divide by 8 to get the byte count. */
		memcpy(sllao, iface->if_hwaddr, iface->if_hwaddr_len / 8);
	}

	/*
	 * Mobile IPv6 ext: Advertisement Interval Option to support
	 * movement detection of mobile nodes
	 */

	if (iface->AdvIntervalOpt) {
		struct AdvInterval a_ival;
		uint32_t ival;
		if (iface->MaxRtrAdvInterval < Cautious_MaxRtrAdvInterval) {
			ival = ((iface->MaxRtrAdvInterval + Cautious_MaxRtrAdvInterval_Leeway) * 1000);

		} else {
			ival = (iface->MaxRtrAdvInterval * 1000);
		}
		a_ival.type = ND_OPT_RTR_ADV_INTERVAL;
		a_ival.length = 1;
		a_ival.reserved = 0;
		a_ival.adv_ival = htonl(ival);

		buff_dest = len;
		send_ra_inc_len(&len, sizeof(a_ival));
		memcpy(buff + buff_dest, &a_ival, sizeof(a_ival));
	}

	/*
	 * Mobile IPv6 ext: Home Agent Information Option to support
	 * Dynamic Home Agent Address Discovery
	 */

	if (iface->AdvHomeAgentInfo && (iface->AdvMobRtrSupportFlag || iface->HomeAgentPreference != 0 || iface->HomeAgentLifetime != iface->AdvDefaultLifetime)) {
		struct HomeAgentInfo ha_info;
		ha_info.type = ND_OPT_HOME_AGENT_INFO;
		ha_info.length = 1;
		ha_info.flags_reserved = (iface->AdvMobRtrSupportFlag) ? ND_OPT_HAI_FLAG_SUPPORT_MR : 0;
		ha_info.preference = htons(iface->HomeAgentPreference);
		ha_info.lifetime = htons(iface->HomeAgentLifetime);

		buff_dest = len;
		send_ra_inc_len(&len, sizeof(ha_info));
		memcpy(buff + buff_dest, &ha_info, sizeof(ha_info));
	}

	lowpanco = iface->AdvLowpanCoList;

	/*
	 * Add 6co option
	 */

	if (lowpanco) {
		struct nd_opt_6co *co;
		co = (struct nd_opt_6co *)(buff + len);

		send_ra_inc_len(&len, sizeof(*co));

		co->nd_opt_6co_type = ND_OPT_6CO;
		co->nd_opt_6co_len = 3;
		co->nd_opt_6co_context_len = lowpanco->ContextLength;
		co->nd_opt_6co_c = lowpanco->ContextCompressionFlag;
		co->nd_opt_6co_cid = lowpanco->AdvContextID;
		co->nd_opt_6co_valid_lifetime = lowpanco->AdvLifeTime;
		co->nd_opt_6co_con_prefix = lowpanco->AdvContextPrefix;
	}

	abroo = iface->AdvAbroList;

	/*
	 * Add ABRO option
	 */

	if (abroo) {
		struct nd_opt_abro *abro;
		abro = (struct nd_opt_abro *)(buff + len);

		send_ra_inc_len(&len, sizeof(*abro));

		abro->nd_opt_abro_type = ND_OPT_ABRO;
		abro->nd_opt_abro_len = 3;
		abro->nd_opt_abro_ver_low = abroo->Version[1];
		abro->nd_opt_abro_ver_high = abroo->Version[0];
		abro->nd_opt_abro_valid_lifetime = abroo->ValidLifeTime;
		abro->nd_opt_abro_6lbr_address = abroo->LBRaddress;
	}

	err = really_send(dest, iface->if_index, iface->if_addr, buff, len);

	if (err < 0) {
		if (!iface->IgnoreIfMissing || !(errno == EINVAL || errno == ENODEV))
			flog(LOG_WARNING, "sendmsg: %s", strerror(errno));
		else
			dlog(LOG_DEBUG, 3, "sendmsg: %s", strerror(errno));
	}

	return 0;
}
Exemplo n.º 25
0
/* Handle all of the extended 'q' packets.  */
static
void handle_query (char *arg_own_buf, int *new_packet_len_p)
{
   static struct inferior_list_entry *thread_ptr;

   /* qRcmd, monitor command handling.  */
   if (strncmp ("qRcmd,", arg_own_buf, 6) == 0) {
      char *p = arg_own_buf + 6;
      int cmdlen = strlen(p)/2;
      char cmd[cmdlen+1];
      
      if (unhexify (cmd, p, cmdlen) != cmdlen) {
         write_enn (arg_own_buf);
         return;
      }
      cmd[cmdlen] = '\0';
       
      if (handle_gdb_monitor_command (cmd)) {
         /* In case the command is from a standalone vgdb,
            connection will be closed soon => flush the output. */
         VG_(message_flush) ();
         write_ok (arg_own_buf);
         return;
      } else {
         /* cmd not recognised */
         VG_(gdb_printf) 
            ("command '%s' not recognised\n"
             "In gdb,     try 'monitor help'\n"
             "In a shell, try 'vgdb help'\n",
             cmd);
         write_ok (arg_own_buf);
         return;
      }
   }

   /* provide some valgrind specific info in return to qThreadExtraInfo. */
   if (strncmp ("qThreadExtraInfo,", arg_own_buf, 17) == 0) {
      unsigned long gdb_id;
      struct thread_info *ti;
      ThreadState *tst;
      char status[100];
      
      gdb_id = strtoul (&arg_own_buf[17], NULL, 16);
      ti = gdb_id_to_thread (gdb_id);
      if (ti != NULL) {
         tst = (ThreadState *) inferior_target_data (ti);
         /* Additional info is the tid and the thread status. */
         VG_(snprintf) (status, sizeof(status), "tid %d %s",
                        tst->tid, 
                        VG_(name_of_ThreadStatus)(tst->status));
         hexify (arg_own_buf, status, strlen(status));
         return;
      } else {
         write_enn (arg_own_buf);
         return;
      }
   }
   
   if (strcmp ("qAttached", arg_own_buf) == 0) {
      /* tell gdb to always detach, never kill the process */
      arg_own_buf[0] = '1';
      arg_own_buf[1] = 0;
      return;
   }

   if (strcmp ("qSymbol::", arg_own_buf) == 0) {
      /* We have no symbol to read. */
      write_ok (arg_own_buf);
      return;
   }

   if (strcmp ("qfThreadInfo", arg_own_buf) == 0) {
      thread_ptr = all_threads.head;
      VG_(sprintf) (arg_own_buf, "m%x", 
                    thread_to_gdb_id ((struct thread_info *)thread_ptr));
      thread_ptr = thread_ptr->next;
      return;
   }

   if (strcmp ("qsThreadInfo", arg_own_buf) == 0) {
      if (thread_ptr != NULL) {
         VG_(sprintf) (arg_own_buf, "m%x", 
                       thread_to_gdb_id ((struct thread_info *)thread_ptr));
         thread_ptr = thread_ptr->next;
         return;
      } else {
         VG_(sprintf) (arg_own_buf, "l");
         return;
      }
   }

   if (valgrind_target_xml(VG_(clo_vgdb_shadow_registers)) != NULL
        && strncmp ("qXfer:features:read:", arg_own_buf, 20) == 0) {
      CORE_ADDR ofs;
      unsigned int len, doc_len;
      char *annex = NULL;
      // First, the annex is extracted from the packet received.
      // Then, it is replaced by the corresponding file name.
      int fd;

      /* Grab the annex, offset, and length.  */
      if (decode_xfer_read (arg_own_buf + 20, &annex, &ofs, &len) < 0) {
         strcpy (arg_own_buf, "E00");
         return;
      }
      
      if (strcmp (annex, "target.xml") == 0) {
         annex = valgrind_target_xml(VG_(clo_vgdb_shadow_registers));
         if (annex != NULL && VG_(clo_vgdb_shadow_registers)) {
            /* Ensure the shadow registers are initialized. */
            initialize_shadow_low(True);
         }
         if (annex == NULL) {
            strcpy (arg_own_buf, "E00");
            return;
         }
      }

      {
         char doc[VG_(strlen)(VG_(libdir)) + 1 + VG_(strlen)(annex) + 1];
         struct vg_stat stat_doc;
         char toread[len];
         int len_read;

         VG_(sprintf)(doc, "%s/%s", VG_(libdir), annex);
         fd = VG_(fd_open) (doc, VKI_O_RDONLY, 0);
         if (fd == -1) {
            strcpy (arg_own_buf, "E00");
            return;
         }
         if (VG_(fstat) (fd, &stat_doc) != 0) {
            VG_(close) (fd);
            strcpy (arg_own_buf, "E00");
            return;
         }
         doc_len = stat_doc.size;
         
         if (len > PBUFSIZ - POVERHSIZ)
            len = PBUFSIZ - POVERHSIZ;

         if (ofs > doc_len) {
            write_enn (arg_own_buf);
            VG_(close) (fd);
            return;
         }
         VG_(lseek) (fd, ofs, VKI_SEEK_SET);
         len_read = VG_(read) (fd, toread, len);
         *new_packet_len_p = write_qxfer_response (arg_own_buf, toread,
                                                   len_read, ofs + len_read < doc_len);
         VG_(close) (fd);
         return;
      }
   }

   if (strncmp ("qXfer:auxv:read:", arg_own_buf, 16) == 0) {
      unsigned char *data;
      int n;
      CORE_ADDR ofs;
      unsigned int len;
      char *annex;

      /* Reject any annex; grab the offset and length.  */
      if (decode_xfer_read (arg_own_buf + 16, &annex, &ofs, &len) < 0
          || annex[0] != '\0') {
         strcpy (arg_own_buf, "E00");
         return;
      }

      if (len > PBUFSIZ - 2)
         len = PBUFSIZ - 2;
      data = malloc (len);

      {
         UWord *client_auxv = VG_(client_auxv);
         unsigned int client_auxv_len = 0;
         while (*client_auxv != 0) {
            dlog(4, "auxv %lld %llx\n",
                 (ULong)*client_auxv,
                 (ULong)*(client_auxv+1));
            client_auxv++;
            client_auxv++;
            client_auxv_len += 2 * sizeof(UWord);
         }
         client_auxv_len += 2 * sizeof(UWord);
         dlog(4, "auxv len %d\n", client_auxv_len);

         if (ofs >= client_auxv_len)
            n = -1;
         else {
            n = client_auxv_len - ofs;
            VG_(memcpy) (data, (unsigned char *) VG_(client_auxv), n);
         }
      }

      if (n < 0)
         write_enn (arg_own_buf);
      else if (n > len)
         *new_packet_len_p = write_qxfer_response (arg_own_buf, data, len, 1);
      else
         *new_packet_len_p = write_qxfer_response (arg_own_buf, data, n, 0);
      
      free (data);
      
      return;
   }


   /* Protocol features query.  */
   if (strncmp ("qSupported", arg_own_buf, 10) == 0
       && (arg_own_buf[10] == ':' || arg_own_buf[10] == '\0')) {
      VG_(sprintf) (arg_own_buf, "PacketSize=%x", PBUFSIZ - 1);
      /* Note: max packet size including frame and checksum, but without
         trailing null byte, which is not sent/received. */
      
      strcat (arg_own_buf, ";QStartNoAckMode+");
      strcat (arg_own_buf, ";QPassSignals+");
      if (VG_(client_auxv))
         strcat (arg_own_buf, ";qXfer:auxv:read+");

      if (valgrind_target_xml(VG_(clo_vgdb_shadow_registers)) != NULL) {
         strcat (arg_own_buf, ";qXfer:features:read+");
         /* if a new gdb connects to us, we have to reset the register
            set to the normal register sets to allow this new gdb to
            decide to use or not the shadow registers.
            
            Note that the reset is only done for gdb that are sending
            qSupported packets. If a user first connected with a recent
            gdb using shadow registers and then with a very old gdb
            that does not use qSupported packet, then the old gdb will
            not properly connect. */
         initialize_shadow_low(False);
      }
      return;
   }

   /* Otherwise we didn't know what packet it was.  Say we didn't
      understand it.  */
   arg_own_buf[0] = 0;
}
Exemplo n.º 26
0
static int parse_dir (const int fd, const char *root, const char *burl, const char *path, int opt,
    char **m, size_t *o, size_t *s, int *num,
    void (*print_fn)(const int what, const char*, const char*, const char*, time_t, char**, size_t*, size_t*, int *) ) {
  DIR  *D;
  struct dirent *dd;
  char dn[MAX_PATH];
  int rv = 0;
  snprintf(dn, MAX_PATH, "%s%s%s", root, SL_SEP(root), path);

  debugmsg(DEBUG_ICS, "IndexDir: indexing '%s'\n", dn);
  if (!(D = opendir (dn)))  {
    dlog(LOG_WARNING, "IndexDir: could not open dir '%s'\n", dn);
    return -1;
  }

  while ((dd = readdir (D))) {
    struct stat fs;
    char rn[MAX_PATH]; // absolute, starting at local root /
    if (dd->d_name[0] == '.') continue; // make optional
#if 0
    int delen = strlen(d->d_name);
    if (delen == 1 && dd->d_name[0] == '.') continue; // '.'
    if (delen == 2 && dd->d_name[0] == '.' && dd->d_name[1] == '.') continue; // '..'
#endif

    snprintf(rn, MAX_PATH, "%s/%s", dn, dd->d_name);
    if(stat(rn, &fs) == 0) { // XXX lstat vs stat
      char fn[MAX_PATH]; // relative to this *root.
      snprintf(fn, MAX_PATH, "%s%s%s", path, SL_SEP(path), dd->d_name);
      if (S_ISDIR(fs.st_mode)) {
        if ((opt&OPT_FLAT) == OPT_FLAT) {
          char pn[MAX_PATH];
          snprintf(pn, MAX_PATH, "%s%s%s/", path, SL_SEP(path), dd->d_name);
          if ((rv = parse_dir(fd, root, burl, pn, opt, m, o, s, num, print_fn))) {
            if (rv == -1) rv = 0; // opendir failed -- continue
            else break;
          }
          if (strlen(*m) > 0) {
            int tx = CSEND(fd, (*m));
            if (tx > 0) {
              (*o) = 0;
              (*m)[0] = '\0';
            } else if (tx < 0) {
              debugmsg(DEBUG_ICS, "abort indexing\n");
              rv = -2;
              break;
            }
          }
        } else {
          print_fn(0, burl, path, dd->d_name, fs.st_mtime, m, o, s, num);
        }
      }
      else if (
#ifndef HAVE_WINDOWS
          S_ISLNK(fs.st_mode) ||
#endif
          S_ISREG(fs.st_mode)) {
        parse_direntry(root, burl, path, dd->d_name, fs.st_mtime, opt, m, o, s, num, print_fn);
      }
    }
  }
  closedir(D);
  return rv;
}
Exemplo n.º 27
0
static FILE *
open_locked_mtab(char *mnttabname, char *mode, char *fs)
{
  FILE *mfp = NULL;

  /*
   * There is a possible race condition if two processes enter
   * this routine at the same time.  One will be blocked by the
   * exclusive lock below (or by the shared lock in setmntent)
   * and by the time the second process has the exclusive lock
   * it will be on the wrong underlying object.  To check for this
   * the mtab file is stat'ed before and after all the locking
   * sequence, and if it is a different file then we assume that
   * it may be the wrong file (only "may", since there is another
   * race between the initial stat and the setmntent).
   *
   * Simpler solutions to this problem are invited...
   */
  int racing = 2;
  int rc;
  int retries = 0;
  struct stat st_before, st_after;

  if (mnt_file) {
#ifdef DEBUG
    dlog("Forced close on %s in read_mtab", mnttabname);
#endif /* DEBUG */
    endmntent(mnt_file);
    mnt_file = NULL;
  }
again:
  if (mfp) {
    endmntent(mfp);
    mfp = NULL;
  }
  if (stat(mnttabname, &st_before) < 0) {
    plog(XLOG_ERROR, "%s: stat: %m", mnttabname);
    if (errno == ESTALE) {
      /* happens occasionally */
      sleep(1);
      goto again;
    }
    /*
     * If 'mnttabname' file does not exist give setmntent() a
     * chance to create it (depending on the mode).
     * Otherwise, bail out.
     */
    else if (errno != ENOENT) {
      return 0;
    }
  }
eacces:
  mfp = setmntent(mnttabname, mode);
  if (!mfp) {
    /*
     * Since setmntent locks the descriptor, it
     * is possible it can fail... so retry if
     * needed.
     */
    if (errno == EACCES || errno == EAGAIN) {
#ifdef DEBUG
      dlog("Blocked, trying to obtain exclusive mtab lock");
#endif /* DEBUG */
      goto eacces;
    } else if (errno == ENFILE && retries++ < NFILE_RETRIES) {
      sleep(1);
      goto eacces;
    }
    plog(XLOG_ERROR, "setmntent(\"%s\", \"%s\"): %m", mnttabname, mode);
    return 0;
  }
  /*
   * At this point we have an exclusive lock on the mount list,
   * but it may be the wrong one so...
   */

  /*
   * Need to get an exclusive lock on the current
   * mount table until we have a new copy written
   * out, when the lock is released in free_mntlist.
   * flock is good enough since the mount table is
   * not shared between machines.
   */
  do
    rc = lock(fileno(mfp));
  while (rc < 0 && errno == EINTR);
  if (rc < 0) {
    plog(XLOG_ERROR, "Couldn't lock %s: %m", mnttabname);
    endmntent(mfp);
    return 0;
  }
  /*
   * Now check whether the mtab file has changed under our feet
   */
  if (stat(mnttabname, &st_after) < 0) {
    plog(XLOG_ERROR, "%s: stat", mnttabname);
    goto again;
  }
  if (st_before.st_dev != st_after.st_dev ||
      st_before.st_ino != st_after.st_ino) {
    struct timeval tv;
    if (racing == 0) {
      /* Sometimes print a warning */
      plog(XLOG_WARNING,
	   "Possible mount table race - retrying %s", fs);
    }
    racing = (racing + 1) & 3;
    /*
     * Take a nap.  From: Doug Kingston <*****@*****.**>
     */
    tv.tv_sec = 0;
    tv.tv_usec = (am_mypid & 0x07) << 17;
    if (tv.tv_usec)
      if (select(0, (voidp) 0, (voidp) 0, (voidp) 0, &tv) < 0)
	plog(XLOG_WARNING, "mtab nap failed: %m");

    goto again;
  }
  return mfp;
}
Exemplo n.º 28
0
int main(int argc, char *argv[]) {

    SOS_runtime *my_sos;

    int i;
    int elem;
    int next_elem;
    char pub_title[SOS_DEFAULT_STRING_LEN] = {0};
    char elem_name[SOS_DEFAULT_STRING_LEN] = {0};
    SOS_pub *pub;
    double time_now;
    double time_start;

    int    MAX_SEND_COUNT;
    int    ITERATION_SIZE;
    int    PUB_ELEM_COUNT;
    int    JITTER_ENABLED;
    double JITTER_INTERVAL;

    MPI_Init(&argc, &argv);

    /* Process command-line arguments */
    if ( argc < 5 ) { fprintf(stderr, "%s\n", USAGE); exit(1); }

    MAX_SEND_COUNT  = -1;
    ITERATION_SIZE  = -1;
    PUB_ELEM_COUNT  = -1;
    JITTER_ENABLED  = 0;
    JITTER_INTERVAL = 0.0;

    for (elem = 1; elem < argc; ) {
        if ((next_elem = elem + 1) == argc) {
            fprintf(stderr, "%s\n", USAGE);
            exit(1);
        }

        if ( strcmp(argv[elem], "-i"  ) == 0) {
            ITERATION_SIZE  = atoi(argv[next_elem]);
        } else if ( strcmp(argv[elem], "-m"  ) == 0) {
            MAX_SEND_COUNT  = atoi(argv[next_elem]);
        } else if ( strcmp(argv[elem], "-p"  ) == 0) {
            PUB_ELEM_COUNT  = atoi(argv[next_elem]);
        } else if ( strcmp(argv[elem], "-j"  ) == 0) {
            JITTER_INTERVAL = strtod(argv[next_elem], NULL);
            JITTER_ENABLED = 1;
        } else {
            fprintf(stderr, "Unknown flag: %s %s\n", argv[elem], argv[next_elem]);
        }
        elem = next_elem + 1;
    }

    if ( (MAX_SEND_COUNT < 1)
         || (ITERATION_SIZE < 1)
         || (PUB_ELEM_COUNT < 1)
         || (JITTER_INTERVAL < 0.0) )
        { fprintf(stderr, "%s\n", USAGE); exit(1); }


    /* Example variables. */
    char    *str_node_id  = getenv("HOSTNAME");
    char    *str_prog_ver = "1.0";
    char     var_string[100] = {0};
    int      var_int;
    double   var_double;
    
    my_sos = SOS_init( &argc, &argv, SOS_ROLE_CLIENT, SOS_LAYER_APP);
    SOS_SET_CONTEXT(my_sos, "demo_app.main");

    srandom(my_sos->my_guid);

    printf("demo_app starting...\n"); fflush(stdout);
    
    dlog(0, "Creating a pub...\n");

    pub = SOS_pub_create(my_sos, "demo", SOS_NATURE_CREATE_OUTPUT);
    dlog(0, "  ... pub->guid  = %ld\n", pub->guid);

    dlog(0, "Manually configuring some pub metadata...\n");
    strcpy (pub->prog_ver, str_prog_ver);
    pub->meta.channel     = 1;
    pub->meta.nature      = SOS_NATURE_EXEC_WORK;
    pub->meta.layer       = SOS_LAYER_APP;
    pub->meta.pri_hint    = SOS_PRI_DEFAULT;
    pub->meta.scope_hint  = SOS_SCOPE_DEFAULT;
    pub->meta.retain_hint = SOS_RETAIN_DEFAULT;


    dlog(0, "Packing a couple values...\n");
    var_int = 1234567890;
    snprintf(var_string, 100, "Hello, world!");

    var_double = 0.0;

    int pos = -1;
    for (i = 0; i < PUB_ELEM_COUNT; i++) {
        snprintf(elem_name, SOS_DEFAULT_STRING_LEN, "example_dbl_%d", i);
        pos = SOS_pack(pub, elem_name, SOS_VAL_TYPE_DOUBLE, &var_double);
        dlog(0, "   pub->data[%d]->guid == %" SOS_GUID_FMT "\n", pos, pub->data[pos]->guid);
        var_double += 0.0000001;
    }


    dlog(0, "Announcing\n");
    SOS_announce(pub);

    dlog(0, "Re-packing --> Publishing %d values for %d times per iteration:\n",
           PUB_ELEM_COUNT,
           ITERATION_SIZE);
           
    SOS_TIME( time_start );
    int mils = 0;
    int ones = 0;
 
    for (ones = 0; ones < ITERATION_SIZE; ones++) {
        for (i = 0; i < PUB_ELEM_COUNT; i++) {
            snprintf(elem_name, SOS_DEFAULT_STRING_LEN, "example_dbl_%d", i);
            SOS_pack(pub, elem_name, SOS_VAL_TYPE_DOUBLE, &var_double);
            var_double += 0.000001;
        }

        SOS_publish(pub);
    }

    /* Catch any stragglers. */
    //SOS_publish(pub);
    dlog(0, "  ... done.\n");

    dlog(0, "demo_app finished successfully!\n");
    SOS_finalize(my_sos);
    MPI_Finalize();
    return (EXIT_SUCCESS);
}
Exemplo n.º 29
0
void smugglecom_driver(int cn,int ret,int lastact)
{
	struct smugglecom_data *dat;
	struct staffer_ppd *ppd;
        int co,in,didsay=0,talkdir=0;
	struct msg *msg,*next;

        dat=set_data(cn,DRD_SMUGGLECOMDRIVER,sizeof(struct smugglecom_data));
	if (!dat) return;	// oops...

	// loop through our messages
	for (msg=ch[cn].msg; msg; msg=next) {
		next=msg->next;

                // did we see someone?
		if (msg->type==NT_CHAR) {
			
                        co=msg->dat1;

			// dont talk to other NPCs
			if (!(ch[co].flags&CF_PLAYER)) { remove_message(cn,msg); continue; }

			// dont talk to players without connection
			if (ch[co].driver==CDR_LOSTCON) { remove_message(cn,msg); continue; }
			
			// only talk every ten seconds
			if (ticker<dat->last_talk+TICKS*4) { remove_message(cn,msg); continue; }

			if (ticker<dat->last_talk+TICKS*10 && dat->current_victim!=co) { remove_message(cn,msg); continue; }

                        // dont talk to someone we cant see, and dont talk to ourself
			if (!char_see_char(cn,co) || cn==co) { remove_message(cn,msg); continue; }

			// dont talk to someone far away
			if (char_dist(cn,co)>10) { remove_message(cn,msg); continue; }

                        // get current status with player
                        ppd=set_data(co,DRD_STAFFER_PPD,sizeof(struct staffer_ppd));

                        if (ppd) {
                                switch(ppd->smugglecom_state) {
					case 0:         quiet_say(cn,"Greetings, %s!",ch[co].name);
							questlog_open(co,35);
							ppd->smugglecom_state++; didsay=1;
                                                        break;
					case 1:		quiet_say(cn,"I want you to find a book for me called 'the contraband book', which contains the names of four of the smuggler's most precious items.");
							ppd->smugglecom_state++; didsay=1;
                                                        break;
					case 2:		//quiet_say(cn,"Also, I will reward you for every piece of contraband you bring me. ");
                                                        //ppd->smugglecom_state++; didsay=1;
                                                        //break;
							// fall through intended for now
					case 3:		quiet_say(cn,"Go now, and may Ishtar be with you.");
							ppd->smugglecom_state=4; didsay=1;
                                                        break;
					case 4:		break;
					case 5:		if (questlog_isdone(co,36)) { ppd->smugglecom_state=7; break; }
							quiet_say(cn,"It lists four important items which I want you to retrieve: the Rainbow Pearls, the Crimson Ring, the Leopard Cape, and the Emerald Necklace. Find them, and bring them to me.");
							questlog_open(co,36);
							ppd->smugglecom_state++; didsay=1;
                                                        break;
					case 6:		if (ppd->smugglecom_bits==15) {
								ppd->smugglecom_state++;
								questlog_done(co,36);
							}
							break;
					case 7:		quiet_say(cn,"Thank you, you are of great help in hurting the smuggler's operations.");
							if (questlog_isdone(co,37)) { ppd->smugglecom_state=10; break; }
                                                        quiet_say(cn,"Now, as a final task, I want you to kill the smuggler's leader. Good luck!");
							questlog_open(co,37);
							ppd->smugglecom_state++; didsay=1;
							break;
					case 8:		break;
					case 9:		quiet_say(cn,"Thank you for helping us, %s, you have been of great value.",ch[co].name);
							ppd->smugglecom_state++; didsay=1;
							questlog_done(co,37);
                                                        break;
					case 10:	break;

	

				}
				if (didsay) {
					dat->last_talk=ticker;
					talkdir=offset2dx(ch[cn].x,ch[cn].y,ch[co].x,ch[co].y);
					dat->current_victim=co;
					notify_area(ch[cn].x,ch[cn].y,NT_NPC,NTID_DIDSAY,cn,0);
				}
			}
		}

                // talk back
		if (msg->type==NT_TEXT) {
			co=msg->dat3;

			if (ch[co].flags&CF_PLAYER) {
				ppd=set_data(co,DRD_STAFFER_PPD,sizeof(struct staffer_ppd));
                                switch((didsay=analyse_text_driver(cn,msg->dat1,(char*)msg->dat2,co))) {
					case 2:         if (ppd && ppd->smugglecom_state<=4) { dat->last_talk=0; ppd->smugglecom_state=0; }
							if (ppd && ppd->smugglecom_state>=5 && ppd->smugglecom_state<=6) { dat->last_talk=0; ppd->smugglecom_state=5; }
							if (ppd && ppd->smugglecom_state>=7 && ppd->smugglecom_state<=8) { dat->last_talk=0; ppd->smugglecom_state=7; }
							break;				
					case 3:		if (ch[co].flags&CF_GOD) ppd->smugglecom_bits=ppd->smugglecom_state=0;
							break;
				}
                                if (didsay) {
					talkdir=offset2dx(ch[cn].x,ch[cn].y,ch[co].x,ch[co].y);
					dat->current_victim=co;
				}
			}
		}

		// got an item?
		if (msg->type==NT_GIVE) {
			co=msg->dat1;

                        if ((in=ch[cn].citem)) {	// we still have it
				int val;

				ppd=set_data(co,DRD_STAFFER_PPD,sizeof(struct staffer_ppd));

				if (it[in].ID==IID_STAFF_SMUGGLEBOOK && ppd && ppd->smugglecom_state<=4 && (ch[co].flags&CF_PLAYER)) {
					quiet_say(cn,"Thank you for the book, %s.",ch[co].name);
                                        questlog_done(co,35);
					destroy_item_byID(co,IID_STAFF_SMUGGLEBOOK);
                                        ppd->smugglecom_state=5;
				} else if (it[in].ID==IID_STAFF_SMUGGLEPEARLS && ppd && !(ppd->smugglecom_bits&SMUGGLEBIT_PEARLS) && (ch[co].flags&CF_PLAYER)) {
					quiet_say(cn,"Thank you for bringing back the %s, %s.",it[in].name,ch[co].name);
					
					val=questlog_scale(questlog_count(co,36),1000);
                                        dlog(co,0,"Received %d exp for doing quest Contraband I for the %d. time (nominal value %d exp)",val,questlog_count(co,36)+1,1000);
					give_exp(co,min(val,level_value(ch[co].level)/4));
					
					ppd->smugglecom_bits|=SMUGGLEBIT_PEARLS;
				} else if (it[in].ID==IID_STAFF_SMUGGLERING && ppd && !(ppd->smugglecom_bits&SMUGGLEBIT_RING) && (ch[co].flags&CF_PLAYER)) {
					quiet_say(cn,"Thank you for bringing back the %s, %s.",it[in].name,ch[co].name);
					
					val=questlog_scale(questlog_count(co,36),1000);
                                        dlog(co,0,"Received %d exp for doing quest Contraband II for the %d. time (nominal value %d exp)",val,questlog_count(co,36)+1,1000);
					give_exp(co,min(val,level_value(ch[co].level)/4));
					
					ppd->smugglecom_bits|=SMUGGLEBIT_RING;
				} else if (it[in].ID==IID_STAFF_SMUGGLECAPE && ppd && !(ppd->smugglecom_bits&SMUGGLEBIT_CAPE) && (ch[co].flags&CF_PLAYER)) {
					quiet_say(cn,"Thank you for bringing back the %s, %s.",it[in].name,ch[co].name);
					
					val=questlog_scale(questlog_count(co,36),1000);
                                        dlog(co,0,"Received %d exp for doing quest Contraband III for the %d. time (nominal value %d exp)",val,questlog_count(co,36)+1,1000);
					give_exp(co,min(val,level_value(ch[co].level)/4));
					
					ppd->smugglecom_bits|=SMUGGLEBIT_CAPE;
				} else if (it[in].ID==IID_STAFF_SMUGGLENECKLACE && ppd && !(ppd->smugglecom_bits&SMUGGLEBIT_NECKLACE) && (ch[co].flags&CF_PLAYER)) {
					quiet_say(cn,"Thank you for bringing back the %s, %s.",it[in].name,ch[co].name);
					
					val=questlog_scale(questlog_count(co,36),1000);
                                        dlog(co,0,"Received %d exp for doing quest Contraband IV for the %d. time (nominal value %d exp)",val,questlog_count(co,36)+1,1000);
					give_exp(co,min(val,level_value(ch[co].level)/4));
					
					ppd->smugglecom_bits|=SMUGGLEBIT_NECKLACE;
				} else {
                                        quiet_say(cn,"Thou hast better use for this than I do. Well, if there is use for it at all.");
					if (give_char_item(co,ch[cn].citem)) ch[cn].citem=0;					
				}
				
				// let it vanish, then
				if (ch[cn].citem) {
					destroy_item(ch[cn].citem);
					ch[cn].citem=0;
				}
			}
		}

		remove_message(cn,msg);
	}

        // do something. whenever possible, call do_idle with as high a tick count
	// as reasonable when doing nothing.

	dat->amgivingback=0;

	if (talkdir) turn(cn,talkdir);

	if (dat->last_talk+TICKS*30<ticker) {
		if (secure_move_driver(cn,ch[cn].tmpx,ch[cn].tmpy,DX_LEFT,ret,lastact)) return;
	}

        do_idle(cn,TICKS);
}
Exemplo n.º 30
0
void
get_args(int argc, char *argv[])
{
    int opt_ch;
    FILE *fp = stdin;
    char getopt_arguments[] = "+nprvSa:c:d:k:l:o:t:w:x:y:C:D:F:T:O:HA:";
    char *getopt_args;

#ifdef HAVE_GNU_GETOPT
    getopt_args = getopt_arguments;
#else /* ! HAVE_GNU_GETOPT */
    getopt_args = &getopt_arguments[1];
#endif /* HAVE_GNU_GETOPT */

    /* if no arguments were passed, try to use /etc/amd.conf file */
    if (argc <= 1)
        use_conf_file = 1;

    while ((opt_ch = getopt(argc, argv, getopt_args)) != -1)
        switch (opt_ch) {

        case 'a':
            if (*optarg != '/') {
                fprintf(stderr, "%s: -a option must begin with a '/'\n",
                        am_get_progname());
                exit(1);
            }
            gopt.auto_dir = optarg;
            break;

        case 'c':
            gopt.am_timeo = atoi(optarg);
            if (gopt.am_timeo <= 0)
                gopt.am_timeo = AM_TTL;
            break;

        case 'd':
            gopt.sub_domain = optarg;
            break;

        case 'k':
            gopt.karch = optarg;
            break;

        case 'l':
            gopt.logfile = optarg;
            break;

        case 'n':
            gopt.flags |= CFM_NORMALIZE_HOSTNAMES;
            break;

        case 'o':
            gopt.op_sys_ver = optarg;
            break;

        case 'p':
            gopt.flags |= CFM_PRINT_PID;
            break;

        case 'r':
            gopt.flags |= CFM_RESTART_EXISTING_MOUNTS;
            break;

        case 't':
            /* timeo.retrans */
        {
            char *dot = strchr(optarg, '.');
            if (dot)
                *dot = '\0';
            if (*optarg) {
                gopt.amfs_auto_timeo = atoi(optarg);
            }
            if (dot) {
                gopt.amfs_auto_retrans = atoi(dot + 1);
                *dot = '.';
            }
        }
        break;

        case 'v':
            fputs(get_version_string(), stderr);
            exit(0);
            break;

        case 'w':
            gopt.am_timeo_w = atoi(optarg);
            if (gopt.am_timeo_w <= 0)
                gopt.am_timeo_w = AM_TTL_W;
            break;

        case 'x':
            usage += switch_option(optarg);
            break;

        case 'y':
#ifdef HAVE_MAP_NIS
            gopt.nis_domain = optarg;
#else /* not HAVE_MAP_NIS */
            plog(XLOG_USER, "-y: option ignored.  No NIS support available.");
#endif /* not HAVE_MAP_NIS */
            break;

        case 'A':
            gopt.arch = optarg;
            break;

        case 'C':
            gopt.cluster = optarg;
            break;

        case 'D':
#ifdef DEBUG
            usage += debug_option(optarg);
#else /* not DEBUG */
            fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n",
                    am_get_progname());
#endif /* not DEBUG */
            break;

        case 'F':
            conf_file = optarg;
            use_conf_file = 1;
            break;

        case 'H':
            goto show_usage;
            break;

        case 'O':
            gopt.op_sys = optarg;
            break;

        case 'S':
            gopt.flags &= ~CFM_PROCESS_LOCK; /* turn process locking off */
            break;

        case 'T':
            conf_tag = optarg;
            break;

        default:
            usage = 1;
            break;
        }

    /*
     * amd.conf file: if not command-line arguments were used, or if -F was
     * specified, then use that amd.conf file.  If the file cannot be opened,
     * abort amd.  If it can be found, open it, parse it, and then close it.
     */
    if (use_conf_file && conf_file) {
        fp = fopen(conf_file, "r");
        if (!fp) {
            char buf[128];
            sprintf(buf, "Amd configuration file (%s)", conf_file);
            perror(buf);
            exit(1);
        }
        yyin = fp;
        yyparse();
        fclose(fp);
        if (process_last_regular_map() != 0)
            exit(1);
    }

    /* make sure there are some default options defined */
    if (xlog_level_init == ~0) {
        switch_option("");
    }
#ifdef DEBUG
    usage += switch_option("debug");
#endif /* DEBUG */

    /* log information regarding amd.conf file */
    if (use_conf_file && conf_file)
        plog(XLOG_INFO, "using configuration file %s", conf_file);

#ifdef HAVE_MAP_LDAP
    /* ensure that if ldap_base is specified, that also ldap_hostports is */
    if (gopt.ldap_hostports && !gopt.ldap_base) {
        fprintf(stderr, "must specify both ldap_hostports and ldap_base\n");
        exit(1);
    }
#endif /* HAVE_MAP_LDAP */

    if (usage)
        goto show_usage;

    while (optind <= argc - 2) {
        char *dir = argv[optind++];
        char *map = argv[optind++];
        char *opts = "";
        if (argv[optind] && *argv[optind] == '-')
            opts = &argv[optind++][1];

        root_newmap(dir, opts, map, NULL);
    }

    if (optind == argc) {
        /*
         * Append domain name to hostname.
         * sub_domain overrides hostdomain
         * if given.
         */
        if (gopt.sub_domain)
            hostdomain = gopt.sub_domain;
        if (*hostdomain == '.')
            hostdomain++;
        strcat(hostd, ".");
        strcat(hostd, hostdomain);

#ifdef MOUNT_TABLE_ON_FILE
#ifdef DEBUG
        amuDebug(D_MTAB)
        mnttab_file_name = DEBUG_MNTTAB;
        else
#endif /* DEBUG */
            mnttab_file_name = MNTTAB_FILE_NAME;
#else /* not MOUNT_TABLE_ON_FILE */
        amuDebug(D_MTAB)
        dlog("-D mtab option ignored");
# ifdef MNTTAB_FILE_NAME
        mnttab_file_name = MNTTAB_FILE_NAME;
# endif /* MNTTAB_FILE_NAME */
#endif /* not MOUNT_TABLE_ON_FILE */

        if (switch_to_logfile(gopt.logfile, orig_umask) != 0)
            plog(XLOG_USER, "Cannot switch logfile");

        /*
         * If the kernel architecture was not specified
         * then use the machine architecture.
         */
        if (gopt.karch == 0)
            gopt.karch = gopt.arch;

        if (gopt.cluster == 0)
            gopt.cluster = hostdomain;

        if (gopt.amfs_auto_timeo <= 0)
            gopt.amfs_auto_timeo = AMFS_AUTO_TIMEO;
        if (gopt.amfs_auto_retrans <= 0)
            gopt.amfs_auto_retrans = AMFS_AUTO_RETRANS;
        if (gopt.amfs_auto_retrans <= 0)
            gopt.amfs_auto_retrans = 3;	/* XXX */
        return;
    }