// The hook caller
 static Ret call(Args... a)
 {
     return hook()(original(), a...);
 }
 // Constructs passing information to the static variables
 function_hooker(hook_type hooker)
 {
     hook() = hooker;
     original() = MakeCALL(addr, raw_ptr(call)).get();
 }
Beispiel #3
0
static grub_err_t
apple_partition_map_iterate (grub_disk_t disk,
			     int (*hook) (grub_disk_t disk,
					  const grub_partition_t partition))
{
  struct grub_partition part;
  struct grub_apple_header aheader;
  struct grub_apple_part apart;
  struct grub_disk raw;
  int partno = 0;
  unsigned pos = GRUB_DISK_SECTOR_SIZE;

  /* Enforce raw disk access.  */
  raw = *disk;
  raw.partition = 0;

  part.partmap = &grub_apple_partition_map;

  if (grub_disk_read (&raw, 0, 0, sizeof (aheader), (char *) &aheader))
    return grub_errno;

  if (grub_be_to_cpu16 (aheader.magic) != GRUB_APPLE_HEADER_MAGIC)
    {
      grub_dprintf ("partition",
		    "bad magic (found 0x%x; wanted 0x%x\n",
		    grub_be_to_cpu16 (aheader.magic),
		    GRUB_APPLE_HEADER_MAGIC);
      goto fail;
    }

  for (;;)
    {
      if (grub_disk_read (&raw, pos / GRUB_DISK_SECTOR_SIZE,
			  pos % GRUB_DISK_SECTOR_SIZE,
			  sizeof (struct grub_apple_part),  (char *) &apart))
	return grub_errno;

      if (grub_be_to_cpu16 (apart.magic) != GRUB_APPLE_PART_MAGIC)
	{
	  grub_dprintf ("partition",
			"partition %d: bad magic (found 0x%x; wanted 0x%x\n",
			partno, grub_be_to_cpu16 (apart.magic),
			GRUB_APPLE_PART_MAGIC);
	  break;
	}

      part.start = grub_be_to_cpu32 (apart.first_phys_block);
      part.len = grub_be_to_cpu32 (apart.blockcnt);
      part.offset = pos;
      part.index = partno;

      grub_dprintf ("partition",
		    "partition %d: name %s, type %s, start 0x%x, len 0x%x\n",
		    partno, apart.partname, apart.parttype,
		    grub_be_to_cpu32 (apart.first_phys_block),
		    grub_be_to_cpu32 (apart.blockcnt));

      if (hook (disk, &part))
	return grub_errno;

      if (grub_be_to_cpu32 (apart.first_phys_block)
	  == GRUB_DISK_SECTOR_SIZE * 2)
	return 0;

      pos += sizeof (struct grub_apple_part);
      partno++;
    }

  if (pos != GRUB_DISK_SECTOR_SIZE)
    return 0;

 fail:
  return grub_error (GRUB_ERR_BAD_PART_TABLE,
		     "Apple partition map not found.");
}
Beispiel #4
0
__attribute__((constructor)) void load(int argc, const char **argv, const char **envp, const char **apple, struct ProgramVars *pvars) {
  hook("_puts", test, pvars->mh);
}
Beispiel #5
0
static void init(void) {
    hook("init() called inside weak-import.");
}
Beispiel #6
0
static void shutdown(void) {
    hook("shutdown() called inside weak-import.");
}
Beispiel #7
0
static int
grub_ext2_iterate_dir (grub_fshelp_node_t dir,
		       int (*hook) (const char *filename,
				    enum grub_fshelp_filetype filetype,
				    grub_fshelp_node_t node,
				    void *closure),
		       void *closure)
{
  unsigned int fpos = 0;
  struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;

  if (! diro->inode_read)
    {
      grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
      if (grub_errno)
	return 0;
    }

  /* Search the file.  */
  while (fpos < grub_le_to_cpu32 (diro->inode.size))
    {
      struct ext2_dirent dirent;

      grub_ext2_read_file (diro, 0, 0, 0, fpos, sizeof (struct ext2_dirent),
			   (char *) &dirent);
      if (grub_errno)
	return 0;

      if (dirent.direntlen == 0)
        return 0;

      if (dirent.namelen != 0)
	{
	  char filename[dirent.namelen + 1];
	  struct grub_fshelp_node *fdiro;
	  enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN;

	  grub_ext2_read_file (diro, 0, 0, 0,
			       fpos + sizeof (struct ext2_dirent),
			       dirent.namelen, filename);
	  if (grub_errno)
	    return 0;

	  fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
	  if (! fdiro)
	    return 0;

	  fdiro->data = diro->data;
	  fdiro->ino = grub_le_to_cpu32 (dirent.inode);

	  filename[dirent.namelen] = '\0';

	  if (dirent.filetype != FILETYPE_UNKNOWN)
	    {
	      fdiro->inode_read = 0;

	      if (dirent.filetype == FILETYPE_DIRECTORY)
		type = GRUB_FSHELP_DIR;
	      else if (dirent.filetype == FILETYPE_SYMLINK)
		type = GRUB_FSHELP_SYMLINK;
	      else if (dirent.filetype == FILETYPE_REG)
		type = GRUB_FSHELP_REG;
	    }
	  else
	    {
	      /* The filetype can not be read from the dirent, read
		 the inode to get more information.  */
	      grub_ext2_read_inode (diro->data,
                                    grub_le_to_cpu32 (dirent.inode),
				    &fdiro->inode);
	      if (grub_errno)
		{
		  grub_free (fdiro);
		  return 0;
		}

	      fdiro->inode_read = 1;

	      if ((grub_le_to_cpu16 (fdiro->inode.mode)
		   & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY)
		type = GRUB_FSHELP_DIR;
	      else if ((grub_le_to_cpu16 (fdiro->inode.mode)
			& FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK)
		type = GRUB_FSHELP_SYMLINK;
	      else if ((grub_le_to_cpu16 (fdiro->inode.mode)
			& FILETYPE_INO_MASK) == FILETYPE_INO_REG)
		type = GRUB_FSHELP_REG;
	    }

	  if (hook (filename, type, fdiro, closure))
	    return 1;
	}

      fpos += grub_le_to_cpu16 (dirent.direntlen);
    }

  return 0;
}
Beispiel #8
0
static grub_err_t
pc_partition_map_iterate (grub_disk_t disk,
			  int (*hook) (grub_disk_t disk,
				       const grub_partition_t partition))
{
  struct grub_partition p;
  struct grub_pc_partition pcdata;
  struct grub_pc_partition_mbr mbr;
  struct grub_pc_partition_disk_label label;
  struct grub_disk raw;

  /* Enforce raw disk access.  */
  raw = *disk;
  raw.partition = 0;
  
  p.offset = 0;
  pcdata.ext_offset = 0;
  pcdata.dos_part = -1;
  p.data = &pcdata;
  p.partmap = &grub_pc_partition_map;
  
  while (1)
    {
      int i;
      struct grub_pc_partition_entry *e;
      
      /* Read the MBR.  */
      if (grub_disk_read (&raw, p.offset, 0, sizeof (mbr), (char *) &mbr))
	goto finish;

      /* Check if it is valid.  */
      if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
	return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");

      /* Analyze DOS partitions.  */
      for (p.index = 0; p.index < 4; p.index++)
	{
	  e = mbr.entries + p.index;
	  
	  p.start = p.offset + grub_le_to_cpu32 (e->start);
	  p.len = grub_le_to_cpu32 (e->length);
	  pcdata.bsd_part = -1;
	  pcdata.dos_type = e->type;
	  pcdata.bsd_type = -1;

	  grub_dprintf ("partition",
			"partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",
			p.index, e->flag, pcdata.dos_type,
			(unsigned long long) p.start,
			(unsigned long long) p.len);

	  /* If this is a GPT partition, this MBR is just a dummy.  */
	  if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && p.index == 0)
	    return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr");

	  /* If this partition is a normal one, call the hook.  */
	  if (! grub_pc_partition_is_empty (e->type)
	      && ! grub_pc_partition_is_extended (e->type))
	    {
	      pcdata.dos_part++;
	      
	      if (hook (disk, &p))
		return 1;

	      /* Check if this is a BSD partition.  */
	      if (grub_pc_partition_is_bsd (e->type))
		{
		  /* Check if the BSD label is within the DOS partition.  */
		  if (p.len <= GRUB_PC_PARTITION_BSD_LABEL_SECTOR)
		    return grub_error (GRUB_ERR_BAD_PART_TABLE,
				       "no space for disk label");

		  /* Read the BSD label.  */
		  if (grub_disk_read (&raw,
				      (p.start
				       + GRUB_PC_PARTITION_BSD_LABEL_SECTOR),
				      0,
				      sizeof (label),
				      (char *) &label))
		    goto finish;

		  /* Check if it is valid.  */
		  if (label.magic
		      != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
		    return grub_error (GRUB_ERR_BAD_PART_TABLE,
				       "invalid disk label magic 0x%x",
				       label.magic);

		  for (pcdata.bsd_part = 0;
		       pcdata.bsd_part < grub_cpu_to_le16 (label.num_partitions);
		       pcdata.bsd_part++)
		    {
		      struct grub_pc_partition_bsd_entry *be
			= label.entries + pcdata.bsd_part;

		      p.start = grub_le_to_cpu32 (be->offset);
		      p.len = grub_le_to_cpu32 (be->size);
		      pcdata.bsd_type = be->fs_type;
		      
		      if (be->fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED)
			if (hook (disk, &p))
			  return 1;
		    }
		}
	    }
	  else if (pcdata.dos_part < 4)
	    /* If this partition is a logical one, shouldn't increase the
	       partition number.  */
	    pcdata.dos_part++;
	}

      /* Find an extended partition.  */
      for (i = 0; i < 4; i++)
	{
	  e = mbr.entries + i;
	  
	  if (grub_pc_partition_is_extended (e->type))
	    {
	      p.offset = pcdata.ext_offset + grub_le_to_cpu32 (e->start);
	      if (! pcdata.ext_offset)
		pcdata.ext_offset = p.offset;

	      break;
	    }
	}

      /* If no extended partition, the end.  */
      if (i == 4)
	break;
    }

 finish:
  return grub_errno;
}
Beispiel #9
0
static grub_err_t
grub_cpio_dir (grub_device_t device, const char *path_in,
	       int (*hook) (const char *filename,
			    const struct grub_dirhook_info *info))
{
  struct grub_cpio_data *data;
  grub_disk_addr_t ofs;
  char *prev, *name, *path, *ptr;
  grub_size_t len;
  int symlinknest = 0;

  path = grub_strdup (path_in + 1);
  if (!path)
    return grub_errno;
  canonicalize (path);
  for (ptr = path + grub_strlen (path) - 1; ptr >= path && *ptr == '/'; ptr--)
    *ptr = 0;

  grub_dl_ref (my_mod);

  prev = 0;

  data = grub_cpio_mount (device->disk);
  if (!data)
    {
      grub_free (path);
      return grub_errno;
    }

  len = grub_strlen (path);
  data->hofs = 0;
  while (1)
    {
      grub_int32_t mtime;
      grub_uint32_t mode;
      grub_err_t err;

      if (grub_cpio_find_file (data, &name, &mtime, &ofs, &mode))
	goto fail;

      if (!ofs)
	break;

      if (grub_memcmp (path, name, len) == 0
	  && (name[len] == 0 || name[len] == '/' || len == 0))
	{
	  char *p, *n;

	  n = name + len;
	  while (*n == '/')
	    n++;

	  p = grub_strchr (n, '/');
	  if (p)
	    *p = 0;

	  if (((!prev) || (grub_strcmp (prev, name) != 0)) && *n != 0)
	    {
	      struct grub_dirhook_info info;
	      grub_memset (&info, 0, sizeof (info));
	      info.dir = (p != NULL) || ((mode & ATTR_TYPE) == ATTR_DIR);
	      info.mtime = mtime;
	      info.mtimeset = 1;

	      if (hook (n, &info))
		{
		  grub_free (name);
		  goto fail;
		}
	      grub_free (prev);
	      prev = name;
	    }
	  else
	    {
	      int restart = 0;
	      err = handle_symlink (data, name, &path, mode, &restart);
	      grub_free (name);
	      if (err)
		goto fail;
	      if (restart)
		{
		  len = grub_strlen (path);
		  if (++symlinknest == 8)
		    {
		      grub_error (GRUB_ERR_SYMLINK_LOOP,
				  N_("too deep nesting of symlinks"));
		      goto fail;
		    }
		  ofs = 0;
		}
	    }
	}
      else
	grub_free (name);
      data->hofs = ofs;
    }

fail:

  grub_free (path);
  grub_free (prev);
#ifdef MODE_USTAR
  grub_free (data->linkname);
#endif
  grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}
Beispiel #10
0
static int
grub_memdisk_iterate (int (*hook) (const char *name))
{
  return hook ("memdisk");
}
void
grub_envblk_iterate (grub_envblk_t envblk,
                     int hook (const char *name, const char *value))
{
  char *p, *pend;

  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
  pend = envblk->buf + envblk->size;

  while (p < pend)
    {
      if (*p != '#')
        {
          char *name;
          char *value;
          char *name_start, *name_end, *value_start;
          char *q;
          int ret;

          name_start = p;
          while (p < pend && *p != '=')
            p++;
          if (p == pend)
            /* Broken.  */
            return;
          name_end = p;

          p++;
          value_start = p;
          while (p < pend)
            {
              if (*p == '\n')
                break;
              else if (*p == '\\')
                p += 2;
              else
                p++;
            }

          if (p >= pend)
            /* Broken.  */
            return;

          name = g_malloc (p - name_start + 1);
          if (! name)
            /* out of memory.  */
            return;

          value = name + (value_start - name_start);

          memcpy (name, name_start, name_end - name_start);
          name[name_end - name_start] = '\0';

          for (p = value_start, q = value; *p != '\n'; ++p)
            {
              if (*p == '\\')
                *q++ = *++p;
              else
                *q++ = *p;
            }
          *q = '\0';

          ret = hook (name, value);
          g_free (name);
          if (ret)
            return;
        }

      p = find_next_line (p, pend);
    }
}
Beispiel #12
0
/* Iterate over the susp entries, starting with block SUA_BLOCK on the
   offset SUA_POS with a size of SUA_SIZE bytes.  Hook is called for
   every entry.  */
static grub_err_t
grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off,
			   grub_ssize_t sua_size,
			   grub_err_t (*hook)
			   (struct grub_iso9660_susp_entry *entry, void *hook_arg),
			   void *hook_arg)
{
  char *sua;
  struct grub_iso9660_susp_entry *entry;
  grub_err_t err;

  if (sua_size <= 0)
    return GRUB_ERR_NONE;

  sua = grub_malloc (sua_size);
  if (!sua)
    return grub_errno;

  /* Load a part of the System Usage Area.  */
  err = read_node (node, off, sua_size, sua);
  if (err)
    return err;

  for (entry = (struct grub_iso9660_susp_entry *) sua; (char *) entry < (char *) sua + sua_size - 1 && entry->len > 0;
       entry = (struct grub_iso9660_susp_entry *)
	 ((char *) entry + entry->len))
    {
      /* The last entry.  */
      if (grub_strncmp ((char *) entry->sig, "ST", 2) == 0)
	break;

      /* Additional entries are stored elsewhere.  */
      if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0)
	{
	  struct grub_iso9660_susp_ce *ce;
	  grub_disk_addr_t ce_block;

	  ce = (struct grub_iso9660_susp_ce *) entry;
	  sua_size = grub_le_to_cpu32 (ce->len);
	  off = grub_le_to_cpu32 (ce->off);
	  ce_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ;

	  grub_free (sua);
	  sua = grub_malloc (sua_size);
	  if (!sua)
	    return grub_errno;

	  /* Load a part of the System Usage Area.  */
	  err = grub_disk_read (node->data->disk, ce_block, off,
				sua_size, sua);
	  if (err)
	    return err;

	  entry = (struct grub_iso9660_susp_entry *) sua;
	}

      if (hook (entry, hook_arg))
	{
	  grub_free (sua);
	  return 0;
	}
    }

  grub_free (sua);
  return 0;
}
void uwsgi_corerouter_loop(int id, void *data) {

	int i;

	struct uwsgi_corerouter *ucr = (struct uwsgi_corerouter *) data;

	ucr->cr_stats_server = -1;

	ucr->cr_table = uwsgi_malloc(sizeof(struct corerouter_session *) * uwsgi.max_fd);

	for (i = 0; i < (int) uwsgi.max_fd; i++) {
		ucr->cr_table[i] = NULL;
	}

	ucr->i_am_cheap = ucr->cheap;

	void *events = uwsgi_corerouter_setup_event_queue(ucr, id);

	if (ucr->has_subscription_sockets)
		event_queue_add_fd_read(ucr->queue, ushared->gateways[id].internal_subscription_pipe[1]);


	if (!ucr->socket_timeout)
		ucr->socket_timeout = 60;

	if (!ucr->static_node_gracetime)
		ucr->static_node_gracetime = 30;

	int i_am_the_first = 1;
	for(i=0;i<id;i++) {
		if (!strcmp(ushared->gateways[i].name, ucr->name)) {
			i_am_the_first = 0;
			break;
		}
	}

	if (ucr->stats_server && i_am_the_first) {
		char *tcp_port = strchr(ucr->stats_server, ':');
		if (tcp_port) {
			// disable deferred accept for this socket
			int current_defer_accept = uwsgi.no_defer_accept;
			uwsgi.no_defer_accept = 1;
			ucr->cr_stats_server = bind_to_tcp(ucr->stats_server, uwsgi.listen_queue, tcp_port);
			uwsgi.no_defer_accept = current_defer_accept;
		}
		else {
			ucr->cr_stats_server = bind_to_unix(ucr->stats_server, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
		}

		event_queue_add_fd_read(ucr->queue, ucr->cr_stats_server);
		uwsgi_log("*** %s stats server enabled on %s fd: %d ***\n", ucr->short_name, ucr->stats_server, ucr->cr_stats_server);
	}


	if (ucr->use_socket) {
		ucr->to_socket = uwsgi_get_socket_by_num(ucr->socket_num);
		if (ucr->to_socket) {
			// fix socket name_len
			if (ucr->to_socket->name_len == 0 && ucr->to_socket->name) {
				ucr->to_socket->name_len = strlen(ucr->to_socket->name);
			}
		}
	}

	if (!ucr->pb_base_dir) {
		ucr->pb_base_dir = getenv("TMPDIR");
		if (!ucr->pb_base_dir)
			ucr->pb_base_dir = "/tmp";
	}

	int nevents;

	time_t delta;

	struct uwsgi_rb_timer *min_timeout;

	int new_connection;


	if (ucr->pattern) {
		init_magic_table(ucr->magic_table);
	}

	union uwsgi_sockaddr cr_addr;
	socklen_t cr_addr_len = sizeof(struct sockaddr_un);

	ucr->mapper = uwsgi_cr_map_use_void;

			if (ucr->use_cache) {
				ucr->cache = uwsgi_cache_by_name(ucr->use_cache);
				if (!ucr->cache) {
					uwsgi_log("!!! unable to find cache \"%s\" !!!\n", ucr->use_cache);
					exit(1);
				}
                        	ucr->mapper = uwsgi_cr_map_use_cache;
                        }
                        else if (ucr->pattern) {
                                ucr->mapper = uwsgi_cr_map_use_pattern;
                        }
                        else if (ucr->has_subscription_sockets) {
                                ucr->mapper = uwsgi_cr_map_use_subscription;
				if (uwsgi.subscription_dotsplit) {
                                	ucr->mapper = uwsgi_cr_map_use_subscription_dotsplit;
				}
                        }
                        else if (ucr->base) {
                                ucr->mapper = uwsgi_cr_map_use_base;
                        }
                        else if (ucr->code_string_code && ucr->code_string_function) {
                                ucr->mapper = uwsgi_cr_map_use_cs;
			}
                        else if (ucr->to_socket) {
                                ucr->mapper = uwsgi_cr_map_use_to;
                        }
                        else if (ucr->static_nodes) {
                                ucr->mapper = uwsgi_cr_map_use_static_nodes;
                        }

	ucr->timeouts = uwsgi_init_rb_timer();

	for (;;) {

		time_t now = uwsgi_now();

		// set timeouts and harakiri
		min_timeout = uwsgi_min_rb_timer(ucr->timeouts, NULL);
		if (min_timeout == NULL) {
			delta = -1;
		}
		else {
			delta = min_timeout->value - now;
			if (delta <= 0) {
				corerouter_expire_timeouts(ucr, now);
				delta = 0;
			}
		}

		if (uwsgi.master_process && ucr->harakiri > 0) {
			ushared->gateways_harakiri[id] = 0;
		}

		// wait for events
		nevents = event_queue_wait_multi(ucr->queue, delta, events, ucr->nevents);

		now = uwsgi_now();

		if (uwsgi.master_process && ucr->harakiri > 0) {
			ushared->gateways_harakiri[id] = now + ucr->harakiri;
		}

		if (nevents == 0) {
			corerouter_expire_timeouts(ucr, now);
		}

		for (i = 0; i < nevents; i++) {

			// get the interesting fd
			ucr->interesting_fd = event_queue_interesting_fd(events, i);
			// something bad happened
			if (ucr->interesting_fd < 0) continue;

			// check if the ucr->interesting_fd matches a gateway socket
			struct uwsgi_gateway_socket *ugs = uwsgi.gateway_sockets;
			int taken = 0;
			while (ugs) {
				if (ugs->gateway == &ushared->gateways[id] && ucr->interesting_fd == ugs->fd) {
					if (!ugs->subscription) {
#if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL)
						new_connection = accept4(ucr->interesting_fd, (struct sockaddr *) &cr_addr, &cr_addr_len, SOCK_NONBLOCK);
						if (new_connection < 0) {
							taken = 1;
							break;
						}
#else
						new_connection = accept(ucr->interesting_fd, (struct sockaddr *) &cr_addr, &cr_addr_len);
						if (new_connection < 0) {
							taken = 1;
							break;
						}
						// set socket in non-blocking mode, on non-linux platforms, clients get the server mode
#ifdef __linux__
                                                uwsgi_socket_nb(new_connection);
#endif
#endif
						struct corerouter_session *cr = corerouter_alloc_session(ucr, ugs, new_connection, (struct sockaddr *) &cr_addr, cr_addr_len);
						//something wrong in the allocation
						if (!cr) break;
					}
					else if (ugs->subscription) {
						uwsgi_corerouter_manage_subscription(ucr, id, ugs);
					}

					taken = 1;
					break;
				}


				ugs = ugs->next;
			}

			if (taken) {
				continue;
			}

			// manage internal subscription
			if (ucr->interesting_fd == ushared->gateways[id].internal_subscription_pipe[1]) {
				uwsgi_corerouter_manage_internal_subscription(ucr, ucr->interesting_fd);
			}
			// manage a stats request
			else if (ucr->interesting_fd == ucr->cr_stats_server) {
				corerouter_send_stats(ucr);
			}
			else {
				struct corerouter_peer *peer = ucr->cr_table[ucr->interesting_fd];

				// something is going wrong...
				if (peer == NULL)
					continue;

				// on error, destroy the session
				if (event_queue_interesting_fd_has_error(events, i)) {
					peer->failed = 1;
					corerouter_close_peer(ucr, peer);
					continue;
				}

				// set timeout (in main_peer too)
				peer->timeout = corerouter_reset_timeout_fast(ucr, peer, now);
				peer->session->main_peer->timeout = corerouter_reset_timeout_fast(ucr, peer->session->main_peer, now);

				ssize_t (*hook)(struct corerouter_peer *) = NULL;

				// call event hook
				if (event_queue_interesting_fd_is_read(events, i)) {
					hook = peer->hook_read;	
				}
				else if (event_queue_interesting_fd_is_write(events, i)) {
					hook = peer->hook_write;	
				}

				if (!hook) continue;
				// reset errno (as we use it for internal signalling)
				errno = 0;
				ssize_t ret = hook(peer);
				// connection closed
				if (ret == 0) {
					corerouter_close_peer(ucr, peer);
					continue;
				}
				else if (ret < 0) {
					if (errno == EINPROGRESS) continue;
					// remove keepalive on error
					peer->session->can_keepalive = 0;
					corerouter_close_peer(ucr, peer);
					continue;
				}
				
			}
		}
	}

}
Beispiel #14
0
static int
parse_string (const char *str,
	      int (*hook) (const char *var, grub_size_t varlen),
	      char **put)
{
  const char *ptr;
  int escaped = 0;
  const char *optr;

  for (ptr = str; ptr && *ptr; )
    switch (*ptr)
      {
      case '\\':
	escaped = !escaped;
	if (!escaped && put)
	  *((*put)++) = '\\';
	ptr++;
	break;
      case '$':
	if (escaped)
	  {
	    escaped = 0;
	    if (put)
	      *((*put)++) = *ptr;
	    ptr++;
	    break;
	  }

	ptr++;
	switch (*ptr)
	  {
	  case '{':
	    {
	      optr = ptr + 1;
	      ptr = grub_strchr (optr, '}');
	      if (!ptr)
		break;
	      if (hook (optr, ptr - optr))
		return 1;
	      ptr++;
	      break;
	    }
	  case '0' ... '9':
	    optr = ptr;
	    while (*ptr >= '0' && *ptr <= '9')
	      ptr++;
	    if (hook (optr, ptr - optr))
	      return 1;
	    break;
	  case 'a' ... 'z':
	  case 'A' ... 'Z':
	  case '_':
	    optr = ptr;
	    while ((*ptr >= '0' && *ptr <= '9')
		   || (*ptr >= 'a' && *ptr <= 'z')
		   || (*ptr >= 'A' && *ptr <= 'Z')
		   || *ptr == '_')
	      ptr++;
	    if (hook (optr, ptr - optr))
	      return 1;
	    break;
	  case '?':
	  case '#':
	    if (hook (ptr, 1))
	      return 1;
	    ptr++;
	    break;
	  default:
	    if (put)
	      *((*put)++) = '$';
	  }
	break;
      default:
	if (escaped && put)
	  *((*put)++) = '\\';
	escaped = 0;
	if (put)
	  *((*put)++) = *ptr;
	ptr++;
	break;
      }
  return 0;
}
Beispiel #15
0
void
grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
			   int floppy_disks)
{
  int i;

  clear_seen_devices ();

  /* Floppies.  */
  for (i = 0; i < floppy_disks; i++)
    {
      char name[16];
      struct stat st;

      get_floppy_disk_name (name, i);
      if (stat (name, &st) < 0)
	break;
      /* In floppies, write the map, whether check_device_readable_unique
         succeeds or not, because the user just may not insert floppies.  */
      if (hook (name, 1))
	goto out;
    }

#ifdef __linux__
  {
    DIR *dir = opendir ("/dev/disk/by-id");

    if (dir)
      {
	struct dirent *entry;
	struct device *devs;
	size_t devs_len = 0, devs_max = 1024, i;

	devs = xmalloc (devs_max * sizeof (*devs));

	/* Dump all the directory entries into names, resizing if
	   necessary.  */
	for (entry = readdir (dir); entry; entry = readdir (dir))
	  {
	    /* Skip current and parent directory entries.  */
	    if (strcmp (entry->d_name, ".") == 0 ||
		strcmp (entry->d_name, "..") == 0)
	      continue;
	    /* Skip partition entries.  */
	    if (strstr (entry->d_name, "-part"))
	      continue;
	    /* Skip device-mapper entries; we'll handle the ones we want
	       later.  */
	    if (strncmp (entry->d_name, "dm-", sizeof ("dm-") - 1) == 0)
	      continue;
	    /* Skip RAID entries; they are handled by upper layers.  */
	    if (strncmp (entry->d_name, "md-", sizeof ("md-") - 1) == 0)
	      continue;
	    if (devs_len >= devs_max)
	      {
		devs_max *= 2;
		devs = xrealloc (devs, devs_max * sizeof (*devs));
	      }
	    devs[devs_len].stable =
	      xasprintf ("/dev/disk/by-id/%s", entry->d_name);
	    devs[devs_len].kernel =
	      canonicalize_file_name (devs[devs_len].stable);
	    devs_len++;
	  }

	qsort (devs, devs_len, sizeof (*devs), &compare_devices);

	closedir (dir);

	/* Now add all the devices in sorted order.  */
	for (i = 0; i < devs_len; ++i)
	  {
	    if (check_device_readable_unique (devs[i].stable))
	      {
		if (hook (devs[i].stable, 0))
		  goto out;
	      }
	    free (devs[i].stable);
	    free (devs[i].kernel);
	  }
	free (devs);
      }
  }

  if (have_devfs ())
    {
      i = 0;
      while (1)
	{
	  char discn[32];
	  char name[PATH_MAX];
	  struct stat st;

	  /* Linux creates symlinks "/dev/discs/discN" for convenience.
	     The way to number disks is the same as GRUB's.  */
	  sprintf (discn, "/dev/discs/disc%d", i++);
	  if (stat (discn, &st) < 0)
	    break;

	  if (realpath (discn, name))
	    {
	      strcat (name, "/disc");
	      if (hook (name, 0))
		goto out;
	    }
	}
      goto out;
    }
#endif /* __linux__ */

  /* IDE disks.  */
  for (i = 0; i < 96; i++)
    {
      char name[16];

      get_ide_disk_name (name, i);
      if (check_device_readable_unique (name))
	{
	  if (hook (name, 0))
	    goto out;
	}
    }

#ifdef __linux__
  /* Virtio disks.  */
  for (i = 0; i < 26; i++)
    {
      char name[16];

      get_virtio_disk_name (name, i);
      if (check_device_readable_unique (name))
	{
	  if (hook (name, 0))
	    goto out;
	}
    }

  /* ATARAID disks.  */
  for (i = 0; i < 8; i++)
    {
      char name[20];

      get_ataraid_disk_name (name, i);
      if (check_device_readable_unique (name))
	{
	  if (hook (name, 0))
	    goto out;
        }
    }

  /* Xen virtual block devices.  */
  for (i = 0; i < 26; i++)
    {
      char name[16];

      get_xvd_disk_name (name, i);
      if (check_device_readable_unique (name))
	{
	  if (hook (name, 0))
	    goto out;
	}
    }
#endif /* __linux__ */

  /* The rest is SCSI disks.  */
  for (i = 0; i < 48; i++)
    {
      char name[16];

      get_scsi_disk_name (name, i);
      if (check_device_readable_unique (name))
	{
	  if (hook (name, 0))
	    goto out;
	}
    }

#ifdef __linux__
  /* This is for DAC960 - we have
     /dev/rd/c<controller>d<logical drive>p<partition>.

     DAC960 driver currently supports up to 8 controllers, 32 logical
     drives, and 7 partitions.  */
  {
    int controller, drive;

    for (controller = 0; controller < 8; controller++)
      {
	for (drive = 0; drive < 15; drive++)
	  {
	    char name[24];

	    get_dac960_disk_name (name, controller, drive);
	    if (check_device_readable_unique (name))
	      {
		if (hook (name, 0))
		  goto out;
	      }
	  }
      }
  }

  /* This is for Mylex Acceleraid - we have
     /dev/rd/c<controller>d<logical drive>p<partition>.  */
  {
    int controller, drive;

    for (controller = 0; controller < 8; controller++)
      {
	for (drive = 0; drive < 15; drive++)
	  {
	    char name[24];

	    get_acceleraid_disk_name (name, controller, drive);
	    if (check_device_readable_unique (name))
	      {
		if (hook (name, 0))
		  goto out;
	      }
	  }
      }
  }

  /* This is for CCISS - we have
     /dev/cciss/c<controller>d<logical drive>p<partition>.  */
  {
    int controller, drive;

    for (controller = 0; controller < 3; controller++)
      {
	for (drive = 0; drive < 16; drive++)
	  {
	    char name[24];

	    get_cciss_disk_name (name, controller, drive);
	    if (check_device_readable_unique (name))
	      {
		if (hook (name, 0))
		  goto out;
	      }
	  }
      }
  }

  /* This is for Compaq Intelligent Drive Array - we have
     /dev/ida/c<controller>d<logical drive>p<partition>.  */
  {
    int controller, drive;

    for (controller = 0; controller < 3; controller++)
      {
	for (drive = 0; drive < 16; drive++)
	  {
	    char name[24];

	    get_ida_disk_name (name, controller, drive);
	    if (check_device_readable_unique (name))
	      {
		if (hook (name, 0))
		  goto out;
	      }
	  }
      }
  }

  /* This is for I2O - we have /dev/i2o/hd<logical drive><partition> */
  {
    char unit;

    for (unit = 'a'; unit < 'f'; unit++)
      {
	char name[24];

	get_i2o_disk_name (name, unit);
	if (check_device_readable_unique (name))
	  {
	    if (hook (name, 0))
	      goto out;
	  }
      }
  }

  /* MultiMediaCard (MMC).  */
  for (i = 0; i < 10; i++)
    {
      char name[16];

      get_mmc_disk_name (name, i);
      if (check_device_readable_unique (name))
	{
	  if (hook (name, 0))
	    goto out;
	}
    }

# ifdef HAVE_DEVICE_MAPPER
#  define dmraid_check(cond, ...) \
  if (! (cond)) \
    { \
      grub_dprintf ("deviceiter", __VA_ARGS__); \
      goto dmraid_end; \
    }

  /* DM-RAID.  */
  if (grub_device_mapper_supported ())
    {
      struct dm_tree *tree = NULL;
      struct dm_task *task = NULL;
      struct dm_names *names = NULL;
      unsigned int next = 0;
      void *top_handle, *second_handle;
      struct dm_tree_node *root, *top, *second;

      /* Build DM tree for all devices.  */
      tree = dm_tree_create ();
      dmraid_check (tree, "dm_tree_create failed\n");
      task = dm_task_create (DM_DEVICE_LIST);
      dmraid_check (task, "dm_task_create failed\n");
      dmraid_check (dm_task_run (task), "dm_task_run failed\n");
      names = dm_task_get_names (task);
      dmraid_check (names, "dm_task_get_names failed\n");
      dmraid_check (names->dev, "No DM devices found\n");
      do
	{
	  names = (void *) names + next;
	  dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev),
					 MINOR (names->dev)),
			   "dm_tree_add_dev (%s) failed\n", names->name);
	  next = names->next;
	}
      while (next);

      /* Walk the second-level children of the inverted tree; that is, devices
	 which are directly composed of non-DM devices such as hard disks.
	 This class includes all DM-RAID disks and excludes all DM-RAID
	 partitions.  */
      root = dm_tree_find_node (tree, 0, 0);
      top_handle = NULL;
      top = dm_tree_next_child (&top_handle, root, 1);
      while (top)
	{
	  second_handle = NULL;
	  second = dm_tree_next_child (&second_handle, top, 1);
	  while (second)
	    {
	      const char *node_name, *node_uuid;
	      char *name;

	      node_name = dm_tree_node_get_name (second);
	      dmraid_check (node_name, "dm_tree_node_get_name failed\n");
	      node_uuid = dm_tree_node_get_uuid (second);
	      dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n");
	      if (strncmp (node_uuid, "DMRAID-", 7) != 0)
		{
		  grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name);
		  goto dmraid_next_child;
		}

	      name = xasprintf ("/dev/mapper/%s", node_name);
	      if (check_device_readable_unique (name))
		{
		  if (hook (name, 0))
		    {
		      free (name);
		      if (task)
			dm_task_destroy (task);
		      if (tree)
			dm_tree_free (tree);
		      goto out;
		    }
		}
	      free (name);

dmraid_next_child:
	      second = dm_tree_next_child (&second_handle, top, 1);
	    }
	  top = dm_tree_next_child (&top_handle, root, 1);
	}

dmraid_end:
      if (task)
	dm_task_destroy (task);
      if (tree)
	dm_tree_free (tree);
    }
# endif /* HAVE_DEVICE_MAPPER */
#endif /* __linux__ */

out:
  clear_seen_devices ();
}