Remove nested functions from device iterators.
* include/grub/arc/arc.h (grub_arc_iterate_devs_hook_t): New type. (grub_arc_iterate_devs): Add hook_data argument. * include/grub/ata.h (grub_ata_dev_iterate_hook_t): New type. (struct grub_ata_dev.iterate): Add hook_data argument. * include/grub/device.h (grub_device_iterate_hook_t): New type. (grub_device_iterate): Add hook_data argument. * include/grub/disk.h (grub_disk_dev_iterate_hook_t): New type. (struct grub_disk_dev.iterate): Add hook_data argument. (grub_disk_dev_iterate): Likewise. * include/grub/gpt_partition.h (grub_gpt_partition_map_iterate): Likewise. * include/grub/msdos_partition.h (grub_partition_msdos_iterate): Likewise. * include/grub/partition.h (grub_partition_iterate_hook_t): New type. (struct grub_partition_map.iterate): Add hook_data argument. (grub_partition_iterate): Likewise. * include/grub/scsi.h (grub_scsi_dev_iterate_hook_t): New type. (struct grub_scsi_dev.iterate): Add hook_data argument. Update all callers.
This commit is contained in:
		
							parent
							
								
									6c0314d638
								
							
						
					
					
						commit
						25239370fd
					
				
					 50 changed files with 1455 additions and 1165 deletions
				
			
		|  | @ -102,248 +102,281 @@ grub_plan9_unload (void) | |||
|   return GRUB_ERR_NONE; | ||||
| } | ||||
| 
 | ||||
| static grub_err_t | ||||
| grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) | ||||
| /* Context for grub_cmd_plan9.  */ | ||||
| struct grub_cmd_plan9_ctx | ||||
| { | ||||
|   grub_file_t file = 0; | ||||
|   void *mem; | ||||
|   grub_size_t memsize, padsize; | ||||
|   struct grub_plan9_header hdr; | ||||
|   char *config, *configptr; | ||||
|   grub_size_t configsize; | ||||
|   char *pmap = NULL; | ||||
|   grub_size_t pmapalloc = 256; | ||||
|   grub_size_t pmapptr = 0; | ||||
|   int noslash = 1; | ||||
|   char prefixes[5][10] = {"dos", "plan9", "ntfs", "linux", "linuxswap"}; | ||||
|   grub_extcmd_context_t ctxt; | ||||
|   grub_file_t file; | ||||
|   char *pmap; | ||||
|   grub_size_t pmapalloc; | ||||
|   grub_size_t pmapptr; | ||||
|   int noslash; | ||||
|   int prefixescnt[5]; | ||||
|   char *bootdisk = NULL, *bootpart = NULL, *bootpath = NULL; | ||||
|   char *bootdisk, *bootpart; | ||||
| }; | ||||
| 
 | ||||
|   auto int fill_partition (grub_disk_t disk, | ||||
| 			   const grub_partition_t partition); | ||||
|   int fill_partition (grub_disk_t disk, | ||||
| 		      const grub_partition_t partition) | ||||
|   { | ||||
|     int file_disk = 0; | ||||
|     int pstart, pend; | ||||
|     if (!noslash) | ||||
|       { | ||||
| 	if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) | ||||
| 	  return 1; | ||||
| 	pmap[pmapptr++] = '/'; | ||||
|       } | ||||
|     noslash = 0; | ||||
| static const char prefixes[5][10] = { | ||||
|   "dos", "plan9", "ntfs", "linux", "linuxswap" | ||||
| }; | ||||
| 
 | ||||
|     file_disk = file->device->disk && disk->id == file->device->disk->id | ||||
|       && disk->dev->id == file->device->disk->dev->id; | ||||
| /* Helper for grub_cmd_plan9.  */ | ||||
| static int | ||||
| fill_partition (grub_disk_t disk, const grub_partition_t partition, void *data) | ||||
| { | ||||
|   struct grub_cmd_plan9_ctx *fill_ctx = data; | ||||
|   int file_disk = 0; | ||||
|   int pstart, pend; | ||||
| 
 | ||||
|     pstart = pmapptr; | ||||
|     if (grub_strcmp (partition->partmap->name, "plan") == 0) | ||||
|       { | ||||
| 	unsigned ptr = partition->index + sizeof ("part ") - 1; | ||||
| 	grub_err_t err; | ||||
| 	disk->partition = partition->parent; | ||||
| 	do | ||||
| 	  { | ||||
| 	    if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) | ||||
| 	      return 1; | ||||
| 	    err = grub_disk_read (disk, 1, ptr, 1, pmap + pmapptr); | ||||
| 	    if (err) | ||||
| 	      { | ||||
| 		disk->partition = 0; | ||||
| 		return err; | ||||
| 	      } | ||||
| 	    ptr++; | ||||
| 	    pmapptr++; | ||||
| 	  } | ||||
| 	while (grub_isalpha (pmap[pmapptr - 1]) | ||||
| 	       || grub_isdigit (pmap[pmapptr - 1])); | ||||
| 	pmapptr--; | ||||
|       } | ||||
|     else | ||||
|       { | ||||
| 	char name[50]; | ||||
| 	int c = 0; | ||||
| 	if (grub_strcmp (partition->partmap->name, "msdos") == 0) | ||||
| 	  { | ||||
| 	    switch (partition->msdostype) | ||||
| 	      { | ||||
| 	      case GRUB_PC_PARTITION_TYPE_PLAN9: | ||||
| 		c = 1; | ||||
| 		break; | ||||
| 	      case GRUB_PC_PARTITION_TYPE_NTFS: | ||||
| 		c = 2; | ||||
| 		break; | ||||
| 	      case GRUB_PC_PARTITION_TYPE_MINIX: | ||||
| 	      case GRUB_PC_PARTITION_TYPE_LINUX_MINIX: | ||||
| 	      case GRUB_PC_PARTITION_TYPE_EXT2FS: | ||||
| 		c = 3; | ||||
| 		break; | ||||
| 	      case GRUB_PC_PARTITION_TYPE_LINUX_SWAP: | ||||
| 		c = 4; | ||||
| 		break; | ||||
| 	      } | ||||
| 	  } | ||||
|   if (!fill_ctx->noslash) | ||||
|     { | ||||
|       if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc, | ||||
| 			     (void **) &fill_ctx->pmap)) | ||||
| 	return 1; | ||||
|       fill_ctx->pmap[fill_ctx->pmapptr++] = '/'; | ||||
|     } | ||||
|   fill_ctx->noslash = 0; | ||||
| 
 | ||||
| 	if (prefixescnt[c] == 0) | ||||
| 	  grub_strcpy (name, prefixes[c]); | ||||
| 	else | ||||
| 	  grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c], | ||||
| 			 prefixescnt[c]); | ||||
| 	prefixescnt[c]++; | ||||
| 	if (grub_extend_alloc (pmapptr + grub_strlen (name) + 1, | ||||
| 			       &pmapalloc, (void **) &pmap)) | ||||
| 	  return 1; | ||||
| 	grub_strcpy (pmap + pmapptr, name); | ||||
| 	pmapptr += grub_strlen (name); | ||||
|       } | ||||
|     pend = pmapptr; | ||||
|     if (grub_extend_alloc (pmapptr + 2 + 25 + 5 + 25, &pmapalloc, | ||||
| 			   (void **) &pmap)) | ||||
|       return 1; | ||||
|     pmap[pmapptr++] = ' '; | ||||
|     grub_snprintf (pmap + pmapptr, 25 + 5 + 25, | ||||
| 		   "%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T, | ||||
| 		   grub_partition_get_start (partition), | ||||
| 		   grub_partition_get_start (partition) | ||||
| 		   + grub_partition_get_len (partition)); | ||||
|     if (file_disk && grub_partition_get_start (partition) | ||||
| 	== grub_partition_get_start (file->device->disk->partition) | ||||
| 	&& grub_partition_get_len (partition) | ||||
| 	== grub_partition_get_len (file->device->disk->partition)) | ||||
|       { | ||||
| 	grub_free (bootpart); | ||||
| 	bootpart = grub_strndup (pmap + pstart, pend - pstart); | ||||
|       } | ||||
|   file_disk = fill_ctx->file->device->disk | ||||
|     && disk->id == fill_ctx->file->device->disk->id | ||||
|     && disk->dev->id == fill_ctx->file->device->disk->dev->id; | ||||
| 
 | ||||
|     pmapptr += grub_strlen (pmap + pmapptr); | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   auto int fill_disk (const char *name); | ||||
|   int fill_disk (const char *name) | ||||
|   { | ||||
|     grub_device_t dev; | ||||
|     char *plan9name = NULL; | ||||
|     unsigned i; | ||||
|     int file_disk = 0; | ||||
| 
 | ||||
|     dev = grub_device_open (name); | ||||
|     if (!dev) | ||||
|       { | ||||
| 	grub_print_error (); | ||||
| 	return 0; | ||||
|       } | ||||
|     if (!dev->disk) | ||||
|       { | ||||
| 	grub_device_close (dev); | ||||
| 	return 0; | ||||
|       } | ||||
|     file_disk = file->device->disk && dev->disk->id == file->device->disk->id | ||||
|       && dev->disk->dev->id == file->device->disk->dev->id; | ||||
|     for (i = 0; ctxt->state[0].args && ctxt->state[0].args[i]; i++) | ||||
|       if (grub_strncmp (name, ctxt->state[0].args[i], grub_strlen (name)) == 0 | ||||
| 	  && ctxt->state[0].args[i][grub_strlen (name)] == '=') | ||||
| 	break; | ||||
|     if (ctxt->state[0].args && ctxt->state[0].args[i]) | ||||
|       plan9name = grub_strdup (ctxt->state[0].args[i] + grub_strlen (name) + 1); | ||||
|     else | ||||
|       switch (dev->disk->dev->id) | ||||
|   pstart = fill_ctx->pmapptr; | ||||
|   if (grub_strcmp (partition->partmap->name, "plan") == 0) | ||||
|     { | ||||
|       unsigned ptr = partition->index + sizeof ("part ") - 1; | ||||
|       grub_err_t err; | ||||
|       disk->partition = partition->parent; | ||||
|       do | ||||
| 	{ | ||||
| 	case GRUB_DISK_DEVICE_BIOSDISK_ID: | ||||
| 	  if (dev->disk->id & 0x80) | ||||
| 	    plan9name = grub_xasprintf ("sdB%u", | ||||
| 					(unsigned) (dev->disk->id & 0x7f)); | ||||
| 	  else | ||||
| 	    plan9name = grub_xasprintf ("fd%u", | ||||
| 					(unsigned) (dev->disk->id & 0x7f)); | ||||
| 	  break; | ||||
| 	  /* Shouldn't happen as Plan9 doesn't work on these platforms.  */ | ||||
| 	case GRUB_DISK_DEVICE_OFDISK_ID: | ||||
| 	case GRUB_DISK_DEVICE_EFIDISK_ID: | ||||
| 
 | ||||
| 	  /* Plan9 doesn't see those.  */ | ||||
| 	default: | ||||
| 
 | ||||
| 	  /* Not sure how to handle those. */ | ||||
| 	case GRUB_DISK_DEVICE_NAND_ID: | ||||
| 	  if (!file_disk) | ||||
| 	  if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc, | ||||
| 				 (void **) &fill_ctx->pmap)) | ||||
| 	    return 1; | ||||
| 	  err = grub_disk_read (disk, 1, ptr, 1, | ||||
| 				fill_ctx->pmap + fill_ctx->pmapptr); | ||||
| 	  if (err) | ||||
| 	    { | ||||
| 	      grub_device_close (dev); | ||||
| 	      return 0; | ||||
| 	      disk->partition = 0; | ||||
| 	      return err; | ||||
| 	    } | ||||
| 	   | ||||
| 	  /* if it's the disk the kernel is loaded from we need to name
 | ||||
| 	     it nevertheless.  */ | ||||
| 	  plan9name = grub_strdup ("sdZ0"); | ||||
| 	  break; | ||||
| 	  ptr++; | ||||
| 	  fill_ctx->pmapptr++; | ||||
| 	} | ||||
|       while (grub_isalpha (fill_ctx->pmap[fill_ctx->pmapptr - 1]) | ||||
| 	     || grub_isdigit (fill_ctx->pmap[fill_ctx->pmapptr - 1])); | ||||
|       fill_ctx->pmapptr--; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       char name[50]; | ||||
|       int c = 0; | ||||
|       if (grub_strcmp (partition->partmap->name, "msdos") == 0) | ||||
| 	{ | ||||
| 	  switch (partition->msdostype) | ||||
| 	    { | ||||
| 	    case GRUB_PC_PARTITION_TYPE_PLAN9: | ||||
| 	      c = 1; | ||||
| 	      break; | ||||
| 	    case GRUB_PC_PARTITION_TYPE_NTFS: | ||||
| 	      c = 2; | ||||
| 	      break; | ||||
| 	    case GRUB_PC_PARTITION_TYPE_MINIX: | ||||
| 	    case GRUB_PC_PARTITION_TYPE_LINUX_MINIX: | ||||
| 	    case GRUB_PC_PARTITION_TYPE_EXT2FS: | ||||
| 	      c = 3; | ||||
| 	      break; | ||||
| 	    case GRUB_PC_PARTITION_TYPE_LINUX_SWAP: | ||||
| 	      c = 4; | ||||
| 	      break; | ||||
| 	    } | ||||
| 	} | ||||
| 
 | ||||
| 	case GRUB_DISK_DEVICE_ATA_ID: | ||||
|       if (fill_ctx->prefixescnt[c] == 0) | ||||
| 	grub_strcpy (name, prefixes[c]); | ||||
|       else | ||||
| 	grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c], | ||||
| 		       fill_ctx->prefixescnt[c]); | ||||
|       fill_ctx->prefixescnt[c]++; | ||||
|       if (grub_extend_alloc (fill_ctx->pmapptr + grub_strlen (name) + 1, | ||||
| 			     &fill_ctx->pmapalloc, (void **) &fill_ctx->pmap)) | ||||
| 	return 1; | ||||
|       grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, name); | ||||
|       fill_ctx->pmapptr += grub_strlen (name); | ||||
|     } | ||||
|   pend = fill_ctx->pmapptr; | ||||
|   if (grub_extend_alloc (fill_ctx->pmapptr + 2 + 25 + 5 + 25, | ||||
| 			 &fill_ctx->pmapalloc, (void **) &fill_ctx->pmap)) | ||||
|     return 1; | ||||
|   fill_ctx->pmap[fill_ctx->pmapptr++] = ' '; | ||||
|   grub_snprintf (fill_ctx->pmap + fill_ctx->pmapptr, 25 + 5 + 25, | ||||
| 		 "%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T, | ||||
| 		 grub_partition_get_start (partition), | ||||
| 		 grub_partition_get_start (partition) | ||||
| 		 + grub_partition_get_len (partition)); | ||||
|   if (file_disk && grub_partition_get_start (partition) | ||||
|       == grub_partition_get_start (fill_ctx->file->device->disk->partition) | ||||
|       && grub_partition_get_len (partition) | ||||
|       == grub_partition_get_len (fill_ctx->file->device->disk->partition)) | ||||
|     { | ||||
|       grub_free (fill_ctx->bootpart); | ||||
|       fill_ctx->bootpart = grub_strndup (fill_ctx->pmap + pstart, | ||||
| 					 pend - pstart); | ||||
|     } | ||||
| 
 | ||||
|   fill_ctx->pmapptr += grub_strlen (fill_ctx->pmap + fill_ctx->pmapptr); | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| /* Helper for grub_cmd_plan9.  */ | ||||
| static int | ||||
| fill_disk (const char *name, void *data) | ||||
| { | ||||
|   struct grub_cmd_plan9_ctx *fill_ctx = data; | ||||
|   grub_device_t dev; | ||||
|   char *plan9name = NULL; | ||||
|   unsigned i; | ||||
|   int file_disk = 0; | ||||
| 
 | ||||
|   dev = grub_device_open (name); | ||||
|   if (!dev) | ||||
|     { | ||||
|       grub_print_error (); | ||||
|       return 0; | ||||
|     } | ||||
|   if (!dev->disk) | ||||
|     { | ||||
|       grub_device_close (dev); | ||||
|       return 0; | ||||
|     } | ||||
|   file_disk = fill_ctx->file->device->disk | ||||
|     && dev->disk->id == fill_ctx->file->device->disk->id | ||||
|     && dev->disk->dev->id == fill_ctx->file->device->disk->dev->id; | ||||
|   for (i = 0; | ||||
|        fill_ctx->ctxt->state[0].args && fill_ctx->ctxt->state[0].args[i]; i++) | ||||
|     if (grub_strncmp (name, fill_ctx->ctxt->state[0].args[i], | ||||
| 		      grub_strlen (name)) == 0 | ||||
| 	&& fill_ctx->ctxt->state[0].args[i][grub_strlen (name)] == '=') | ||||
|       break; | ||||
|   if (fill_ctx->ctxt->state[0].args && fill_ctx->ctxt->state[0].args[i]) | ||||
|     plan9name = grub_strdup (fill_ctx->ctxt->state[0].args[i] | ||||
| 			     + grub_strlen (name) + 1); | ||||
|   else | ||||
|     switch (dev->disk->dev->id) | ||||
|       { | ||||
|       case GRUB_DISK_DEVICE_BIOSDISK_ID: | ||||
| 	if (dev->disk->id & 0x80) | ||||
| 	  plan9name = grub_xasprintf ("sdB%u", | ||||
| 				      (unsigned) (dev->disk->id & 0x7f)); | ||||
| 	else | ||||
| 	  plan9name = grub_xasprintf ("fd%u", | ||||
| 				      (unsigned) (dev->disk->id & 0x7f)); | ||||
| 	break; | ||||
| 	/* Shouldn't happen as Plan9 doesn't work on these platforms.  */ | ||||
|       case GRUB_DISK_DEVICE_OFDISK_ID: | ||||
|       case GRUB_DISK_DEVICE_EFIDISK_ID: | ||||
| 
 | ||||
| 	/* Plan9 doesn't see those.  */ | ||||
|       default: | ||||
| 
 | ||||
| 	/* Not sure how to handle those. */ | ||||
|       case GRUB_DISK_DEVICE_NAND_ID: | ||||
| 	if (!file_disk) | ||||
| 	  { | ||||
| 	    grub_device_close (dev); | ||||
| 	    return 0; | ||||
| 	  } | ||||
| 	 | ||||
| 	/* if it's the disk the kernel is loaded from we need to name
 | ||||
| 	   it nevertheless.  */ | ||||
| 	plan9name = grub_strdup ("sdZ0"); | ||||
| 	break; | ||||
| 
 | ||||
|       case GRUB_DISK_DEVICE_ATA_ID: | ||||
| 	{ | ||||
| 	  int unit; | ||||
| 	  if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) | ||||
| 	    unit = 0; | ||||
| 	  else | ||||
| 	    unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); | ||||
| 	  plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); | ||||
| 	} | ||||
| 	break; | ||||
|       case GRUB_DISK_DEVICE_SCSI_ID: | ||||
| 	if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) | ||||
| 	    == GRUB_SCSI_SUBSYSTEM_PATA) | ||||
| 	  { | ||||
| 	    int unit; | ||||
| 	    if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) | ||||
| 	      unit = 0; | ||||
| 	    else | ||||
| 	      unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); | ||||
| 	      unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, | ||||
| 				   0, 0); | ||||
| 	    plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); | ||||
| 	    break; | ||||
| 	  } | ||||
| 	  break; | ||||
| 	case GRUB_DISK_DEVICE_SCSI_ID: | ||||
| 	  if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) | ||||
| 	      == GRUB_SCSI_SUBSYSTEM_PATA) | ||||
| 	    { | ||||
| 	      int unit; | ||||
| 	      if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) | ||||
| 		unit = 0; | ||||
| 	      else | ||||
| 		unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, | ||||
| 				     0, 0); | ||||
| 	      plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); | ||||
| 	      break; | ||||
| 	    } | ||||
| 	   | ||||
| 	  /* FIXME: how does Plan9 number controllers?
 | ||||
| 	     We probably need save the SCSI devices and sort them  */ | ||||
| 	  plan9name | ||||
| 	    = grub_xasprintf ("sd0%u", (unsigned) | ||||
| 			      ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT) | ||||
| 			       & 0xf)); | ||||
| 	  break; | ||||
| 	} | ||||
|     if (!plan9name) | ||||
|       { | ||||
| 	grub_print_error (); | ||||
| 	return 0; | ||||
| 	 | ||||
| 	/* FIXME: how does Plan9 number controllers?
 | ||||
| 	   We probably need save the SCSI devices and sort them  */ | ||||
| 	plan9name | ||||
| 	  = grub_xasprintf ("sd0%u", (unsigned) | ||||
| 			    ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT) | ||||
| 			     & 0xf)); | ||||
| 	break; | ||||
|       } | ||||
|     if (grub_extend_alloc (pmapptr + grub_strlen (plan9name) | ||||
| 			   + sizeof ("part="), &pmapalloc, | ||||
| 			   (void **) &pmap)) | ||||
|       { | ||||
| 	grub_free (plan9name); | ||||
| 	return 1; | ||||
|       } | ||||
|     grub_strcpy (pmap + pmapptr, plan9name); | ||||
|     pmapptr += grub_strlen (plan9name); | ||||
|     if (!file_disk) | ||||
|   if (!plan9name) | ||||
|     { | ||||
|       grub_print_error (); | ||||
|       return 0; | ||||
|     } | ||||
|   if (grub_extend_alloc (fill_ctx->pmapptr + grub_strlen (plan9name) | ||||
| 			 + sizeof ("part="), &fill_ctx->pmapalloc, | ||||
| 			 (void **) &fill_ctx->pmap)) | ||||
|     { | ||||
|       grub_free (plan9name); | ||||
|     else | ||||
|       { | ||||
| 	grub_free (bootdisk); | ||||
| 	bootdisk = plan9name; | ||||
|       } | ||||
|     grub_strcpy (pmap + pmapptr, "part="); | ||||
|     pmapptr += sizeof ("part=") - 1; | ||||
| 
 | ||||
|     noslash = 1; | ||||
|     grub_memset (prefixescnt, 0, sizeof (prefixescnt)); | ||||
|     if (grub_partition_iterate (dev->disk, fill_partition)) | ||||
|       return 1; | ||||
|     if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) | ||||
|       return 1; | ||||
|     pmap[pmapptr++] = '\n'; | ||||
|     } | ||||
|   grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, plan9name); | ||||
|   fill_ctx->pmapptr += grub_strlen (plan9name); | ||||
|   if (!file_disk) | ||||
|     grub_free (plan9name); | ||||
|   else | ||||
|     { | ||||
|       grub_free (fill_ctx->bootdisk); | ||||
|       fill_ctx->bootdisk = plan9name; | ||||
|     } | ||||
|   grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, "part="); | ||||
|   fill_ctx->pmapptr += sizeof ("part=") - 1; | ||||
| 
 | ||||
|     return 0; | ||||
|   } | ||||
|   fill_ctx->noslash = 1; | ||||
|   grub_memset (fill_ctx->prefixescnt, 0, sizeof (fill_ctx->prefixescnt)); | ||||
|   if (grub_partition_iterate (dev->disk, fill_partition, fill_ctx)) | ||||
|     return 1; | ||||
|   if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc, | ||||
| 			 (void **) &fill_ctx->pmap)) | ||||
|     return 1; | ||||
|   fill_ctx->pmap[fill_ctx->pmapptr++] = '\n'; | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| static grub_err_t | ||||
| grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) | ||||
| { | ||||
|   struct grub_cmd_plan9_ctx fill_ctx = { | ||||
|     .ctxt = ctxt, | ||||
|     .file = 0, | ||||
|     .pmap = NULL, | ||||
|     .pmapalloc = 256, | ||||
|     .pmapptr = 0, | ||||
|     .noslash = 1, | ||||
|     .bootdisk = NULL, | ||||
|     .bootpart = NULL | ||||
|   }; | ||||
|   void *mem; | ||||
|   grub_size_t memsize, padsize; | ||||
|   struct grub_plan9_header hdr; | ||||
|   char *config, *configptr; | ||||
|   grub_size_t configsize; | ||||
|   char *bootpath = NULL; | ||||
| 
 | ||||
|   if (argc == 0) | ||||
|     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); | ||||
|  | @ -354,21 +387,21 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) | |||
|   if (!rel) | ||||
|     goto fail; | ||||
| 
 | ||||
|   file = grub_file_open (argv[0]); | ||||
|   if (! file) | ||||
|   fill_ctx.file = grub_file_open (argv[0]); | ||||
|   if (! fill_ctx.file) | ||||
|     goto fail; | ||||
| 
 | ||||
|   pmap = grub_malloc (pmapalloc); | ||||
|   if (!pmap) | ||||
|   fill_ctx.pmap = grub_malloc (fill_ctx.pmapalloc); | ||||
|   if (!fill_ctx.pmap) | ||||
|     goto fail; | ||||
| 
 | ||||
|   if (grub_disk_dev_iterate (fill_disk)) | ||||
|   if (grub_disk_dev_iterate (fill_disk, &fill_ctx)) | ||||
|     goto fail; | ||||
| 
 | ||||
|   if (grub_extend_alloc (pmapptr + 1, &pmapalloc, | ||||
| 			 (void **) &pmap)) | ||||
|   if (grub_extend_alloc (fill_ctx.pmapptr + 1, &fill_ctx.pmapalloc, | ||||
| 			 (void **) &fill_ctx.pmap)) | ||||
|     goto fail; | ||||
|   pmap[pmapptr] = 0; | ||||
|   fill_ctx.pmap[fill_ctx.pmapptr] = 0; | ||||
| 
 | ||||
|   { | ||||
|     char *file_name = grub_strchr (argv[0], ')'); | ||||
|  | @ -379,17 +412,19 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) | |||
|     if (*file_name) | ||||
|       file_name++; | ||||
| 
 | ||||
|     if (bootpart) | ||||
|       bootpath = grub_xasprintf ("%s!%s!%s", bootdisk, bootpart, file_name); | ||||
|     if (fill_ctx.bootpart) | ||||
|       bootpath = grub_xasprintf ("%s!%s!%s", fill_ctx.bootdisk, | ||||
| 				 fill_ctx.bootpart, file_name); | ||||
|     else | ||||
|       bootpath = grub_xasprintf ("%s!%s", bootdisk, file_name); | ||||
|     grub_free (bootdisk); | ||||
|     grub_free (bootpart); | ||||
|       bootpath = grub_xasprintf ("%s!%s", fill_ctx.bootdisk, file_name); | ||||
|     grub_free (fill_ctx.bootdisk); | ||||
|     grub_free (fill_ctx.bootpart); | ||||
|   } | ||||
|   if (!bootpath) | ||||
|     goto fail; | ||||
| 
 | ||||
|   if (grub_file_read (file, &hdr, sizeof (hdr)) != (grub_ssize_t) sizeof (hdr)) | ||||
|   if (grub_file_read (fill_ctx.file, &hdr, | ||||
| 		      sizeof (hdr)) != (grub_ssize_t) sizeof (hdr)) | ||||
|     { | ||||
|       if (!grub_errno) | ||||
| 	grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), | ||||
|  | @ -420,7 +455,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) | |||
|       configsize += grub_strlen (argv[i]) + 1; | ||||
|   } | ||||
|   configsize += (sizeof ("bootfile=") - 1) + grub_strlen (bootpath) + 1; | ||||
|   configsize += pmapptr; | ||||
|   configsize += fill_ctx.pmapptr; | ||||
|   /* Terminating \0.  */ | ||||
|   configsize++; | ||||
| 
 | ||||
|  | @ -452,7 +487,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) | |||
| 	*configptr++ = '\n'; | ||||
|       } | ||||
|   } | ||||
|   configptr = grub_stpcpy (configptr, pmap); | ||||
|   configptr = grub_stpcpy (configptr, fill_ctx.pmap); | ||||
| 
 | ||||
|   { | ||||
|     grub_relocator_chunk_t ch; | ||||
|  | @ -471,7 +506,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) | |||
|     grub_memcpy (ptr, &hdr, sizeof (hdr)); | ||||
|     ptr += sizeof (hdr); | ||||
| 
 | ||||
|     if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.text_size)) | ||||
|     if (grub_file_read (fill_ctx.file, ptr, grub_be_to_cpu32 (hdr.text_size)) | ||||
| 	!= (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size)) | ||||
|       { | ||||
| 	if (!grub_errno) | ||||
|  | @ -487,7 +522,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) | |||
|     grub_memset (ptr, 0, padsize); | ||||
|     ptr += padsize; | ||||
| 
 | ||||
|     if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.data_size)) | ||||
|     if (grub_file_read (fill_ctx.file, ptr, grub_be_to_cpu32 (hdr.data_size)) | ||||
| 	!= (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size)) | ||||
|       { | ||||
| 	if (!grub_errno) | ||||
|  | @ -508,10 +543,10 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) | |||
|   return GRUB_ERR_NONE; | ||||
| 
 | ||||
|  fail: | ||||
|   grub_free (pmap); | ||||
|   grub_free (fill_ctx.pmap); | ||||
| 
 | ||||
|   if (file) | ||||
|     grub_file_close (file); | ||||
|   if (fill_ctx.file) | ||||
|     grub_file_close (fill_ctx.file); | ||||
| 
 | ||||
|   grub_plan9_unload (); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue