コード例 #1
0
ファイル: color.c プロジェクト: LucaBongiorni/poly-engine
/**
 * Generate the color pattern for a given color structure
 * @param t color structure
 * @param text text to color (not used on this function)
 * @param pattern pattern will be save on this buffer
 */
int		revm_colorpattern(color_t *t, char *text, char *pattern)
{
  char		bo[16], ul[16], fg[16], bg[16];
  u_short      	set = 0;

  NOPROFILER_IN();
  
  if (t == NULL || (!t->bground && !t->fground && !t->bold && !t->underline))
    NOPROFILER_ROUT(-1); 

  /* Set every element */
  COLOR_SET_ELEMENT(t->bold, bo, COLOR_BOLD);
  COLOR_SET_ELEMENT(t->underline, ul, COLOR_UNDERLINE);
  COLOR_SET_ELEMENT(t->fground, fg, t->fground);
  COLOR_SET_ELEMENT(t->bground, bg, t->bground);

  snprintf(pattern, COLOR_TOKEN_LEN - 1,
	   "%%s%s%s%s%sm%%s%s%um%%s",
	   (t->bold > 0 ? bo : ""),
	   (t->underline > 0 ? ul : ""),
	   (t->fground > 0 ? fg : ""),
	   (t->bground > 0 ? bg : ""),
	   S_STARTCOLOR,
	   COLOR_NONE);

  NOPROFILER_ROUT(0); 
}
コード例 #2
0
ファイル: dwarf2-utils.c プロジェクト: kejiewei/eresi
/**
 * Read a signed leb128 number as describe on the dwarf2 documentation 
 * a little bit optimize
 * @param data pointer to a buffer where we'll read
 * @param bread store size readed
 * @return final value
 */
long 			edfmt_read_leb128(void *data, u_int *bread)
{
  long			sum = 0;
  u_int			read = 0;
  u_char 		c;
  u_int			s = 0;

  NOPROFILER_IN();

  do {
    c = *(u_char *) (data + read) & 0xFF; 
    read++;
    sum |= ((long)(c & 127) << s);
    
    s += 7;
  } while ((c & 128) != 0);

  if ((s < (8 * sizeof(sum))) && (c & 0x40))
    sum |= -(((long)1) << s);

  if (bread)
    *bread = read;

  NOPROFILER_ROUT(sum);
}
コード例 #3
0
ファイル: liblist.c プロジェクト: breed/elfsh
/**
 * @brief Initialize the hash table
 */
int elist_init(list_t *h, char *name, u_int type)
{
  list_t	*exist;

  NOPROFILER_IN();
  if (type >= aspect_type_nbr)
    {
      fprintf(stderr, "Unable to initialize list %s \n", name);
      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		   "Unable to initialize list", -1);
    }
  exist = elist_find(name);
  if (exist)
    {
#if 1 //__LIST_DEBUG__
      fprintf(stderr, "DEBUG: List %s (%p) already exists in hash with addr %p : NOT CREATING \n", 
	      name, h, exist);
#endif
      NOPROFILER_ROUT(1);
    }
#if __LIST_DEBUG__
  else
    fprintf(stderr, "DEBUG: List %s allocated at %p does not exists in hash : CREATING \n", name, h);
#endif

  bzero(h, sizeof(list_t));
  h->type   = type;
  h->name   = name;
  hash_add(hash_lists, name, h);
  NOPROFILER_ROUT(0);
}
コード例 #4
0
ファイル: color.c プロジェクト: LucaBongiorni/poly-engine
/**
 * Build color text 
 * 
 */
char 		*revm_colorget(char *sp, char *type, void *object)
{
  color_t 	*t;
  char		pattern[COLOR_TOKEN_LEN];
  char		text[COLOR_TOKEN_LEN];
  char		trim_text[COLOR_TOKEN_LEN];
  char		white_s[COLOR_TOKEN_LEN];
  char		white_e[COLOR_TOKEN_LEN];
  char		*pText;

  NOPROFILER_IN();

  if (curtok >= COLOR_TOKENS) 
    {
      printf("[E] %s:%d %s: WARNING !!!! Token overflow (val:%u)\n",
      __FILE__, __LINE__, __FUNCTION__, curtok);
      NOPROFILER_ROUT(NULL);
    }

  //printf("Before token = %016llX \n", (eresi_Addr *) object);
  
  //snprintf(text, COLOR_TOKEN_LEN - 1, sp, object);
  if (strchr(sp, 's') == NULL)
    snprintf(text, COLOR_TOKEN_LEN - 1, sp, *(eresi_Addr *) object);
  else
    snprintf(text, COLOR_TOKEN_LEN - 1, sp, object);

  /* Color isn't activated */
  if (!nocolor)
    NOPROFILER_ROUT(revm_colornothing(sp, object));

  t = revm_colortable(type, text);

  /* Color not found */
  if (t == NULL)
    NOPROFILER_ROUT(revm_colornothing(sp, object));

  /* Invalid pattern */
  if (revm_colorpattern(t, text, pattern) != 0)
    NOPROFILER_ROUT(revm_colornothing(sp, object));

  pText = text;

  memset(white_s, 0x00, COLOR_TOKEN_LEN);
  memset(white_e, 0x00, COLOR_TOKEN_LEN);

  /* Trim the string from blank char */
  if (!trim(text, trim_text, COLOR_TOKEN_LEN, white_s, white_e))
      pText = trim_text;

  snprintf(tokens[curtok], COLOR_TOKEN_LEN - 1, 
	   pattern, white_s, pText, white_e);

  NOPROFILER_ROUT(tokens[curtok++]);
}
コード例 #5
0
ファイル: color.c プロジェクト: LucaBongiorni/poly-engine
/**
 * Retrieve a color information structure from a color type
 * @param type color type
 * @param text text to color to filter for warnstring type
 * @return color structure
 */
color_t 	*revm_colortable(char *type, char *text)
{
  NOPROFILER_IN();

  /* Override color by warning color if we match the alert regex */
  if (world.state.revm_use_alert && 
      !regexec(&world.state.revm_alert, text, 0, 0, 0))
    NOPROFILER_ROUT(hash_get(&t_color_hash, "warnstring"));

  NOPROFILER_ROUT(hash_get(&t_color_hash, type)); 
}
コード例 #6
0
ファイル: color.c プロジェクト: LucaBongiorni/poly-engine
/* Special functions */
char 		*revm_coloradv(char *type, char *pattern, char *text)
{
  char 		*p;

  NOPROFILER_IN();
  p = revm_colorget(pattern, type, text); 
  strncpy(text, p, BUFSIZ);
  text[BUFSIZ-1] = 0;
  curtok--;
  NOPROFILER_ROUT(text);
}
コード例 #7
0
ファイル: io.c プロジェクト: LucaBongiorni/poly-engine
/** 
 * Set workspace configuration to standard I/O 
 */
int		revm_std_io(revmjob_t *job)
{
  NOPROFILER_IN();
  if (!job)
    NOPROFILER_ROUT(0);
  job->ws.io.type      = REVM_IO_STD;
  job->ws.io.input_fd  = 0;
  job->ws.io.input     = revm_stdinput;
  job->ws.io.output_fd = 1;
  job->ws.io.output    = revm_stdoutput;
  NOPROFILER_ROUT(0);
}
コード例 #8
0
ファイル: input.c プロジェクト: kejiewei/eresi
/**
 * @brief Read a new line, avoiding comments and void lines 
 */
char		*revm_getln()
{
  char		*buf;
  char		*sav;
  
  NOPROFILER_IN();
  do
    {
      buf = world.curjob->ws.io.input();
      if (buf == ((char *) REVM_INPUT_VOID))
	NOPROFILER_ROUT((char *) REVM_INPUT_VOID);
      if (buf == NULL)
	NOPROFILER_ROUT(NULL);
      if (!*buf)
	{
	  XFREE(__FILE__, __FUNCTION__, __LINE__,buf);
	  NOPROFILER_ROUT(NULL);
	}
      
      sav = buf;
      while (IS_BLANK(*sav))
	sav++;

      if (!*sav || *sav == REVM_COMMENT_START)
	{
	  revm_log(sav);
	  revm_log("\n");
	  revm_buffer_free(buf); 
	  if (world.state.revm_mode == REVM_STATE_INTERACTIVE ||
	      world.state.revm_mode == REVM_STATE_EMBEDDED)
	    NOPROFILER_ROUT((char*) REVM_INPUT_VOID);

          buf = NULL;
          if (*sav)
	    continue;
	}

      if (world.state.revm_mode != REVM_STATE_SCRIPT)
	{
	  revm_output_nolog("\n");

          /* avoid looping with readline */
          if (revm_is_enabled() && buf == NULL)
	    NOPROFILER_ROUT((char *) REVM_INPUT_VOID);
	  if (revm_is_enabled())
	    break;
	}
    }
  while (buf == NULL);
  
  NOPROFILER_ROUT(buf);
}
コード例 #9
0
ファイル: io.c プロジェクト: LucaBongiorni/poly-engine
/** 
 * Initialize Input/Output hooks 
 */
int		revm_initio()
{
  static int	done = 0;
  revmjob_t	*initial;
  u_int		i;

  NOPROFILER_IN();
  if (done)
    NOPROFILER_ROUT(0);
  done = 1;

  XALLOC(__FILE__, __FUNCTION__, __LINE__,initial, sizeof(revmjob_t), -1);
  memset(initial, 0, sizeof(revmjob_t));

  hash_init(&initial->recur[0].exprs , "job0_rec0_exprs" , 23, ASPECT_TYPE_EXPR);
  hash_init(&initial->recur[0].labels, "job0_rec0_labels", 23, ASPECT_TYPE_STR);

  revm_std_io(initial);
  initial->ws.active	   = 1;
  initial->ws.createtime   = time(&initial->ws.createtime);

  world.initial = world.curjob = initial;
  hash_init(&world.jobs, "jobs", 11, ASPECT_TYPE_UNKNOW);
  hash_add(&world.jobs, "local", initial);
  initial->ws.name = strdup("local");
 
  hash_init(&initial->loaded,    
	    "initial_loaded_files", 
	    51, ASPECT_TYPE_UNKNOW);
  hash_init(&initial->dbgloaded,
	    "initial_dbgloaded_files",
	    11, ASPECT_TYPE_UNKNOW);

  for (i = 0; i < REVM_MAXSRCNEST; i++)
    {
      initial->recur[i].script = NULL;
      initial->recur[i].lstcmd = NULL;
      initial->iter[i].elmidx = REVM_IDX_UNINIT;
    }

  initial->recur[0].funcname = "top-level";

  profiler_setcolor(revm_endline, revm_colorinstr, revm_colorstr, 
		    revm_colorfieldstr, revm_colortypestr, revm_colorend, 
		    revm_colorwarn, revm_colorfunction, revm_colorfilename);
  profiler_setmorecolor(revm_coloradv, revm_colorinstr_fmt, revm_coloraddress,
			revm_colornumber, revm_colorstr_fmt, 
			revm_colorfieldstr_fmt, 
			revm_colortypestr_fmt, revm_colorwarn_fmt);
  NOPROFILER_ROUT(0);
}
コード例 #10
0
ファイル: color.c プロジェクト: LucaBongiorni/poly-engine
/**
 * Return without color 
 * @param sp given string (pattern like %s or %d etc ..)
 * @param object objet to print using the string
 * @return generate string
 */
static char	*revm_colornothing(char *sp, void *object)
{
  NOPROFILER_IN();

  if (!strcmp(sp, "%s"))
    NOPROFILER_ROUT((char *) object);

  if (strchr(sp, 's') == NULL)
    snprintf(tokens[curtok], COLOR_TOKEN_LEN - 1, sp, *(eresi_Addr *) object);
  else
    snprintf(tokens[curtok], COLOR_TOKEN_LEN - 1, sp, object);

  NOPROFILER_ROUT(tokens[curtok++]); 
}
コード例 #11
0
ファイル: input.c プロジェクト: kejiewei/eresi
/** 
 * @brief Read input from the current IO file descriptor 
 */
char		*revm_read_input()
{
  char		tmpbuf[BUFSIZ + 1];
  int		len;
  u_char	wantmore;

  NOPROFILER_IN();
  
  /* In case we are scripting, even readline will use a read */
  for (wantmore = len = 0; len < BUFSIZ; len++)
    switch (read(world.curjob->ws.io.input_fd, tmpbuf + len, 1))
      {
      case 1:
	if (tmpbuf[len] == '\n')
	  {
	    if (len == 0)
	      {
		//fprintf(stderr, "Read length 0 ... \n");
		NOPROFILER_ROUT((char *) REVM_INPUT_VOID);
	      }
	    if (wantmore)
	      {
		len--;
		wantmore = 0;
		continue;
	      }
	    if (world.state.revm_mode == REVM_STATE_EMBEDDED &&
		world.state.revm_side == REVM_SIDE_CLIENT)
	      tmpbuf[len + 1] = 0x00;
	    else
	      tmpbuf[len] = 0x00;
	    goto end;
	  }
	else if ((len > 2 && tmpbuf[len - 1] == ':' && tmpbuf[len] == ':') || tmpbuf[len] == ',')
	  wantmore = 1;
	else
	  wantmore = 0;
	continue;
      default:
	*tmpbuf = 0x00;
	goto end;
      }

 end:
  //fprintf(stderr, "[pid = %u] Read on fd = *%s*\n", getpid(), tmpbuf);
  NOPROFILER_ROUT((*tmpbuf ? strdup(tmpbuf) : NULL));
}
コード例 #12
0
ファイル: input.c プロジェクト: kejiewei/eresi
/** 
 * INPUT IO handler for stdin 
 */
char		*revm_stdinput()
{
  char		*str;

  NOPROFILER_IN();
  str = NULL;

  /* Case if we are using readline */
  if (revm_is_enabled() && world.state.revm_mode != REVM_STATE_SCRIPT)
    {
      str = revm_input_check();
      NOPROFILER_ROUT(str);
    }

  /* If not, read the stdin file descriptor */
  NOPROFILER_ROUT(revm_read_input());
}
コード例 #13
0
ファイル: libhash.c プロジェクト: LucaBongiorni/poly-engine
/** 
 * @brief Initialize the hash table 
 * @param h Pointer to the hash to initialize
 * @param name Name of the hash.
 * @param size Size to document
 * @param type Type to document
 * @param Returns 0 on success, -1 on error or 1 if hash already exists.
 */
int hash_init(hash_t *h, char *name, int size, u_int type)
{
  NOPROFILER_IN();

  /* First checks */
  /* Initialize the global hash table of lists and 
     the global hash table of hash tables */
  if (!hash_hash)
    {
      hash_hash = (hash_t *) calloc(sizeof(hash_t), 1);
      hash_init(hash_hash, "hashes", 51, ASPECT_TYPE_UNKNOW);
    }
  if (type >= aspect_type_nbr)
    {
      fprintf(stderr, "Unable to initialize hash table %s \n", name);
      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		   "Unable to initialize hash table", -1);
    }
  if (h != hash_hash && hash_find(name) && h->ent)
    {
#if __DEBUG__
      fprint(stderr, "Hash table already exists and initialized\n");
#endif
      NOPROFILER_ROUT(1);
    }

  //printf("INIT HASH %s \n", name);
  
  /* Add a new element */
  XALLOC(__FILE__, __FUNCTION__, __LINE__, 
	 h->ent, size * sizeof(listent_t), -1);
  h->size      = size;
  h->type      = type;
  h->elmnbr    = 0;
  h->linearity = 0;
  h->name      = name;
  hash_add(hash_hash, name, h);

  if (!hash_lists)
    {
      hash_lists = (hash_t *) calloc(sizeof(hash_t), 1);
      hash_init(hash_lists, "lists", 51, ASPECT_TYPE_UNKNOW);
    }
  NOPROFILER_ROUT(0);
}
コード例 #14
0
ファイル: color.c プロジェクト: LucaBongiorni/poly-engine
/**
 * Trim a string from blank char and copy it on to argument 
 * @param from source
 * @param to destination
 * @param size buffer size
 * @param start saved starting blank chars (for replace in another place)
 * @param end saved ending blank chars (for replace in another place)
 */
static int	trim(char *from, char *to, u_int size, char *start, char *end)
{
  u_int		len, istart, iend;

  NOPROFILER_IN();

  if (size == 0 || size > COLOR_TOKEN_LEN || from == NULL || to == NULL)
    NOPROFILER_ROUT(-1);

  len = strlen(from);

  /* Speed check */
  if (!IS_BLANK(from[0]) && !IS_BLANK(from[len]))
    NOPROFILER_ROUT(-1);

  /* Before */
  for (istart = 0; istart < len && IS_BLANK(from[istart]); istart++);

  /* All blank, no modifications */
  if (istart == len)
    NOPROFILER_ROUT(-1);

  /* After */
  for (iend = len; iend > 0 && IS_BLANK(from[iend]); iend--);

  iend = len - iend;

  /* Copy the right char on to argument */
  strncpy(to, from + istart, len - istart - iend);
  to[len - istart - iend] = 0x00;

  if (start)
    {
      strncpy(start, from, istart);
      start[istart] = 0x00;
    }

  if (end)
    {
      strncpy(end, from + len - iend, iend);
      end[iend] = 0x00;
    }

  NOPROFILER_ROUT(0);
}
コード例 #15
0
ファイル: color.c プロジェクト: LucaBongiorni/poly-engine
/* Return number of color chars (not total size) */
int		revm_color_count(char *string)
{
  int		count = 0;
  int		len;
  int		i;

  NOPROFILER_IN();

  len = strlen(string);
  for (i = 0; i < len; i++)
    {
      if (string[i] == C_STARTCOLOR)
	{
	  count++;
	  while (i < len && string[i] != 'm')
	    i++;
	}
    }

  NOPROFILER_ROUT(count);
}
コード例 #16
0
ファイル: dwarf2-utils.c プロジェクト: kejiewei/eresi
/**
 * Read an unsigned leb128 number as describe on the dwarf2 documentation 
 * a little bit optimize
 * @param data pointer to a buffer where we'll read
 * @param bread store size readed
 * @return final value
 */
u_long 			edfmt_read_uleb128(void *data, u_int *bread)
{
  u_long		sum = 0;
  u_int			read = 0;
  u_char 		c;
  int			s = 0;

  NOPROFILER_IN();

  do {
    c = *(u_char *) (data + read) & 0xFF; 
    read++;
    sum |= ((u_long)(c & 127) << s);
    
    s += 7;
  } while ((c & 128) != 0);

  if (bread)
    *bread = read;

  NOPROFILER_ROUT(sum);
}
コード例 #17
0
ファイル: color.c プロジェクト: LucaBongiorni/poly-engine
/** 
 * Return total size of colors on a string 
 */
int		revm_color_size(char *string)
{
  int		size = 0;
  int		len;
  int		i;

  NOPROFILER_IN();

  len = strlen(string);
  for (i = 0; i < len; i++)
    {
      if (string[i] == C_STARTCOLOR)
	{
	  while (i < len && string[i] != 'm')
	    {
	      size++;
	      i++;
	    }
	}      
    }

  NOPROFILER_ROUT(size);
}
コード例 #18
0
ファイル: recv.c プロジェクト: LucaBongiorni/poly-engine
/* read a complete packet from given socket */
pkt_t	*dump_recv_pkt(int s)
{
  int	tmp  = 0;
  int	tmp2 = 0;
  int	len  = 0;
  pkt_t *msg;
  int	try = 0;

  NOPROFILER_IN();

  XALLOC(__FILE__, __FUNCTION__, __LINE__,msg, sizeof (pkt_t), NULL);

  /* read fixed size header part */
  do
    {
      tmp2 = recv(s, (void *) msg + tmp,
		  (size_t) (HDR_SIZE - tmp),
		  MSG_DONTWAIT);

      /* connection closed */
      if (tmp2 == 0)
        {
#if !defined(ERESI_INTERNAL)
	  printf("[WW] Connection closed by remote host (1)\n");
#endif
	  XFREE(__FILE__, __FUNCTION__, __LINE__,msg);
	  return  (pkt_t *)(-1);
        }

      /* error */
      if (tmp2 == (-1))
        {
	  /* EAGAIN */
	  if (tmp2 == EAGAIN)
	    {
	      try++;
	      if (try > DUMP_MAXTRY)
		{
		  XFREE(__FILE__, __FUNCTION__, __LINE__, msg);
		  return (pkt_t *)(-1);
		}
	      continue;
	    }
#if !defined(ERESI_INTERNAL)
	  printf("[EE] Error while reading on socket (1)\n");
	  perror("recv");
#endif
	  XFREE(__FILE__, __FUNCTION__, __LINE__, msg);
	  return (pkt_t *)(-1);
        }
      
      len += tmp2;
      tmp += tmp2;

    } while (tmp != (size_t)(HDR_SIZE));

  if (ntohl(msg->path_len) != 0)
    {
      /* read pkt path from header */
      XALLOC(__FILE__, __FUNCTION__, __LINE__, 
	     msg->path, 
	     ntohl(msg->path_len) * sizeof (dump_id_t), 
	     (pkt_t *) -1);

      tmp = 0;
      do 
        {
	  tmp2 = recv(s,
		      (void *) msg->path + tmp,
		      (size_t) ntohl(msg->path_len)*sizeof (dump_id_t) - tmp, 
		      MSG_DONTWAIT);

	  /* connection closed */
	  if (tmp2 == 0)
            {
#if !defined(ERESI_INTERNAL)
	      printf("[WW] Connection closed by remote host (2)\n");
#endif
	      XFREE(__FILE__, __FUNCTION__, __LINE__,msg);
	      return (pkt_t *)(-1);
            }

	  /* error */
	  if (tmp2 == (-1))
            {
	      /* EAGAIN */
	      if (tmp2 == EAGAIN)
		{
		  try++;
		  if (try > DUMP_MAXTRY)
		    {
		      XFREE(__FILE__, __FUNCTION__, __LINE__,msg->path);
		      XFREE(__FILE__, __FUNCTION__, __LINE__,msg);
		      return (pkt_t *)(-1);
		    }
		  continue;
		}
#if !defined(ERESI_INTERNAL)
	      printf("[EE] Error while reading on socket (2)\n");
	      perror("recv");
#endif
	      XFREE(__FILE__, __FUNCTION__, __LINE__,msg->path);
	      XFREE(__FILE__, __FUNCTION__, __LINE__,msg);
	      return  (pkt_t *)(-1);
            }

	  len += tmp2;
	  tmp += tmp2;

        } while (tmp != ntohl(msg->path_len)*sizeof (dump_id_t));
    }
  else
    msg->path=NULL;

  /* read payload */
  if (ntohl(msg->size) != 0)
    {
      XALLOC(__FILE__, __FUNCTION__, __LINE__,msg->data, (size_t) sizeof (char)*ntohl(msg->size), (pkt_t *) -1);

      tmp = 0;
      do
        {
	  tmp2 = recv(s,
		      (void *) msg->data + tmp,
		      (size_t) ntohl(msg->size)*sizeof (char) - tmp, 
		      MSG_DONTWAIT);

	  /* connection closed */
	  if (tmp2 == 0)
            {
#if !defined(ERESI_INTERNAL)
	      printf("[WW] Connection closed by remote host (3)\n");
#endif
	      XFREE(__FILE__, __FUNCTION__, __LINE__,msg->path);
	      XFREE(__FILE__, __FUNCTION__, __LINE__,msg->data);
	      XFREE(__FILE__, __FUNCTION__, __LINE__,msg);
	      return (pkt_t *)(-1);
            }

	  /* error */
	  if (tmp2 == (-1))
            {
	      /* EAGAIN */
	      if (errno == EAGAIN)
		{
		  try++;
		  if (try > DUMP_MAXTRY)
		    {
		      XFREE(__FILE__, __FUNCTION__, __LINE__,msg->path);
		      XFREE(__FILE__, __FUNCTION__, __LINE__,msg->data);
		      XFREE(__FILE__, __FUNCTION__, __LINE__,msg);
		      return (pkt_t *)(-1);
		    }
		  continue;
		}
#if !defined(ERESI_INTERNAL)
	      printf("[EE] Error while reading on socket (3)\n");
	      perror("recv");
#endif
	      XFREE(__FILE__, __FUNCTION__, __LINE__,msg->path);
	      XFREE(__FILE__, __FUNCTION__, __LINE__,msg->data);
	      XFREE(__FILE__, __FUNCTION__, __LINE__,msg);
	      return (pkt_t *)(-1);
            }

	  len += tmp2;
	  tmp += tmp2;

        } while (tmp != ntohl(msg->size)*sizeof (char));
    }
  else
    msg->data = NULL;
  
  return msg;
}


/* handle RR packet */
int		dump_receive_RR(pkt_t *pkt)
{
  dump_id_t	prev;
  dump_id_t	*npath;
  listent_t	*actual;
  int		index;
    
  NOPROFILER_IN();

  if (dump_lookup_RR_recently_seen(pkt->id))
    {
      return (-1);
    }
    
  /* add packet's id to RR table */
  dump_add_RR_recently_seen(pkt->id);

  /* sanity check */
  if (ntohl(pkt->path_len) == 0)
    return (-1);

  /* add myid to path's tail */
  XALLOC(__FILE__, __FUNCTION__, __LINE__,npath, sizeof (dump_id_t)*(ntohl(pkt->path_len)+1), -1);
    
  /* back the previous hop up */
  prev = pkt->path[ntohl(pkt->path_len)-1];

  /* copy previous path's nodes */
  memcpy (npath, pkt->path, ntohl(pkt->path_len)*sizeof (dump_id_t));

  /* is my id ? */
  if (dump_is_myid(pkt->dst))
    {
      /* add myid to path */
      npath[ntohl(pkt->path_len) + 1 - 1] = 
	dump_get_myid(dump_lookup_neighbor (prev));

#if __DEBUG_DUMP__
      printf("[DUMP] dump_receive_RR : it's me !! \n");
#endif
      /* send Rr packet with new id */
      if (dump_send_Rr(pkt->dst, 
		       pkt->src, 
		       (ntohl(pkt->path_len)+1), 
		       npath, 
		       dump_lookup_neighbor(prev), 
		       0) < 0)
        {
#if !defined(ERESI_INTERNAL)
	  fprintf(stderr, "dump_send_Rr error (1)\n");
#endif
	  XFREE(__FILE__, __FUNCTION__, __LINE__,npath);
	  return (-1);
        }
    }
  else
    {
#if __DEBUG_DUMP__
      printf("[DUMP] dump_receive_RR : it's NOT me !! \n");
#endif
      /* send it to all neighbors ... */
      for (index = 0; index < dump_world.ports.size; index++)
	for (actual = &dump_world.ports.ent[index];
	     actual != NULL && actual->key != NULL;
	     actual = actual->next)
	  {
	    /* ... but the sender */
	    if (strcmp(actual->key, inet_ntoa(prev)))
	      {
#if __DEBUG_DUMP__
		printf("[DUMP] dump_receive_RR :"
		       " send to %s, it's NOT the Request sender\n",
		       actual->key);
#endif
		/* add myid to path */
		npath[ntohl(pkt->path_len) + 1 - 1] = 
		  dump_get_myid((long) actual->data);
      
		/* send RR packet with same id */
		if (dump_send_RR(pkt->src, 
				 pkt->dst, 
				 (ntohl(pkt->path_len)+1), 
				 npath, 
				 (long) actual->data, 
				 pkt->id) < 0)
		  {
#if !defined(ERESI_INTERNAL)
		    printf("[EE] dump_send_RR error (2)\n");
#endif
		    XFREE(__FILE__, __FUNCTION__, __LINE__,npath);
		    return (-1);
		  }
	      }

#if __DEBUG_DUMP__ && !defined(ERESI_INTERNAL)
	    else
	      {
		printf("[DUMP] dump_receive_RR :"
		       " don't send to %s, it's the Request sender\n",
		       actual->key);
	      }
#endif
	  }
      
    }
    
  XFREE(__FILE__, __FUNCTION__, __LINE__,npath);
  return 0;
}