[BACK]Return to fdisk.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / fdisk

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sbin/fdisk/fdisk.c between version 1.134 and 1.134.2.4

version 1.134, 2011/08/28 15:46:26 version 1.134.2.4, 2014/05/22 11:37:28
Line 86  __RCSID("$NetBSD$");
Line 86  __RCSID("$NetBSD$");
 #endif  #endif
 #endif /* HAVE_NBTOOL_CONFIG_H */  #endif /* HAVE_NBTOOL_CONFIG_H */
   
   #ifndef DEFAULT_BOOTDIR
 #define DEFAULT_BOOTDIR         "/usr/mdec"  #define DEFAULT_BOOTDIR         "/usr/mdec"
   #endif
   
 #define LE_MBR_MAGIC            htole16(MBR_MAGIC)  #define LE_MBR_MAGIC            htole16(MBR_MAGIC)
 #define LE_MBR_BS_MAGIC         htole16(MBR_BS_MAGIC)  #define LE_MBR_BS_MAGIC         htole16(MBR_BS_MAGIC)
   
 #if defined(__i386__) || defined(__x86_64__)  
 #if !HAVE_NBTOOL_CONFIG_H  
 #include <machine/cpu.h>  
 #endif /* !HAVE_NBTOOL_CONFIG_H */  
 #define BOOTSEL  
 #endif  
   
 #ifdef BOOTSEL  #ifdef BOOTSEL
   
 #define DEFAULT_BOOTCODE        "mbr"  #define DEFAULT_BOOTCODE        "mbr"
Line 155  static char *boot_path = NULL;   /* name
Line 150  static char *boot_path = NULL;   /* name
 #define BOOTSEL_OPTIONS  #define BOOTSEL_OPTIONS
 #define change_part(e, p, id, st, sz, bm) change__part(e, p, id, st, sz)  #define change_part(e, p, id, st, sz, bm) change__part(e, p, id, st, sz)
 #endif  #endif
 #define OPTIONS BOOTSEL_OPTIONS "0123FSafiluvA:b:c:E:r:s:w:"  #define OPTIONS BOOTSEL_OPTIONS "0123FSafiIluvA:b:c:E:r:s:w:z:"
   
 /*  /*
  * Disk geometry and partition alignment.   * Disk geometry and partition alignment.
Line 205  static daddr_t dos_disksectors;
Line 200  static daddr_t dos_disksectors;
   
 #define DOSSECT(s,c)    (((s) & 0x3f) | (((c) >> 2) & 0xc0))  #define DOSSECT(s,c)    (((s) & 0x3f) | (((c) >> 2) & 0xc0))
 #define DOSCYL(c)       ((c) & 0xff)  #define DOSCYL(c)       ((c) & 0xff)
 #define SEC_IN_1M (1024 * 1024 / 512)  #define SEC_IN_1M (1024 * 1024 / secsize)
 #define SEC_TO_MB(sec) ((unsigned int)(((sec) + SEC_IN_1M / 2) / SEC_IN_1M))  #define SEC_TO_MB(sec) ((unsigned int)(((sec) + SEC_IN_1M / 2) / SEC_IN_1M))
 #define SEC_TO_CYL(sec) (((sec) + dos_cylindersectors/2) / dos_cylindersectors)  #define SEC_TO_CYL(sec) (((sec) + dos_cylindersectors/2) / dos_cylindersectors)
   
Line 224  static char *disk_type = NULL;
Line 219  static char *disk_type = NULL;
   
 static int a_flag;              /* set active partition */  static int a_flag;              /* set active partition */
 static int i_flag;              /* init bootcode */  static int i_flag;              /* init bootcode */
   static int I_flag;              /* ignore errors */
 static int u_flag;              /* update partition data */  static int u_flag;              /* update partition data */
 static int v_flag;              /* more verbose */  static int v_flag;              /* more verbose */
 static int sh_flag;             /* Output data as shell defines */  static int sh_flag;             /* Output data as shell defines */
Line 244  static int F_flag = 1;
Line 240  static int F_flag = 1;
 static struct gpt_hdr gpt1, gpt2;       /* GUID partition tables */  static struct gpt_hdr gpt1, gpt2;       /* GUID partition tables */
   
 static struct mbr_sector bootcode[8192 / sizeof (struct mbr_sector)];  static struct mbr_sector bootcode[8192 / sizeof (struct mbr_sector)];
   static ssize_t secsize = 512;   /* sector size */
   static char *iobuf;             /* buffer for non 512 sector I/O */
 static int bootsize;            /* actual size of bootcode */  static int bootsize;            /* actual size of bootcode */
 static int boot_installed;      /* 1 if we've copied code into the mbr */  static int boot_installed;      /* 1 if we've copied code into the mbr */
   
 #if (defined(__i386__) || defined(__x86_64__)) && !HAVE_NBTOOL_CONFIG_H  #if defined(USE_DISKLIST)
 #define USE_DISKLIST  #include <machine/cpu.h>
 static struct disklist *dl;  static struct disklist *dl;
 #endif  #endif
   
Line 278  static void change_active(int);
Line 276  static void change_active(int);
 static void     change_bios_geometry(void);  static void     change_bios_geometry(void);
 static void     dos(int, unsigned char *, unsigned char *, unsigned char *);  static void     dos(int, unsigned char *, unsigned char *, unsigned char *);
 static int      open_disk(int);  static int      open_disk(int);
 static int      read_disk(daddr_t, void *);  static ssize_t  read_disk(daddr_t, void *);
 static int      write_disk(daddr_t, void *);  static ssize_t  write_disk(daddr_t, void *);
 static int      get_params(void);  static int      get_params(void);
 static int      read_s0(daddr_t, struct mbr_sector *);  static int      read_s0(daddr_t, struct mbr_sector *);
 static int      write_mbr(void);  static int      write_mbr(void);
 static int      read_gpt(daddr_t, struct gpt_hdr *);  static int      read_gpt(daddr_t, struct gpt_hdr *);
 static int      delete_gpt(struct gpt_hdr *);  static int      delete_gpt(struct gpt_hdr *);
 static int      yesno(const char *, ...);  static int      yesno(const char *, ...) __printflike(1, 2);
 static int64_t  decimal(const char *, int64_t, int, int64_t, int64_t);  static int64_t  decimal(const char *, int64_t, int, int64_t, int64_t);
 #define DEC_SEC         1               /* asking for a sector number */  #define DEC_SEC         1               /* asking for a sector number */
 #define DEC_RND         2               /* round to end of first track */  #define DEC_RND         2               /* round to end of first track */
Line 323  initvar_disk(const char **diskp)
Line 321  initvar_disk(const char **diskp)
 #endif /* HAVE_NBTOOL_CONFIG_H */  #endif /* HAVE_NBTOOL_CONFIG_H */
 }  }
   
   static int
   getnum(const char *str, int *num)
   {
           char *e;
           long l;
   
           errno = 0;
           l = strtol(str, &e, 0);
           if (str[0] == '\0' || *e != '\0')
                   return -1;
           if (errno == ERANGE && (l == LONG_MAX || l == LONG_MIN))
                   return -1;
           /* XXX: truncation */
           *num = (int)l;
           return 0;
   }
   
   /* [<sysid>][/[<start>][/[<size>][/[<bootmenu>]]]] */
   static int
   parse_s(char *arg, int *csysid, unsigned *cstart, unsigned *csize,
       char **cbootmenu)
   {
           char *ptr;
           int num;
   
           if ((ptr = strchr(arg, '/')) != NULL)
                   *ptr++ = '\0';
   
           if (*arg) {
                   if (getnum(arg, &num) == -1)
                           return -1;
                   *csysid = num;
           }
           if (ptr == NULL)
                   return 0;
   
           arg = ptr;
           if ((ptr = strchr(arg, '/')) != NULL)
                   *ptr++ = '\0';
           if (*arg) {
                   if (getnum(arg, &num) == -1)
                           return -1;
                   *cstart = num;
           }
           if (ptr == NULL)
                   return 0;
   
           arg = ptr;
           if ((ptr = strchr(arg, '/')) != NULL)
                   *ptr++ = '\0';
           if (*arg) {
                   if (getnum(arg, &num) == -1)
                           return -1;
                   *csize = num;
           }
           if (ptr != NULL && *ptr)
                   *cbootmenu = ptr;
           return 0;
   }
   
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
 {  {
Line 333  main(int argc, char *argv[])
Line 391  main(int argc, char *argv[])
         int n;          int n;
 #ifdef BOOTSEL  #ifdef BOOTSEL
         daddr_t default_ptn;            /* start sector of default ptn */          daddr_t default_ptn;            /* start sector of default ptn */
         char *cbootmenu = 0;  
 #endif  #endif
           char *cbootmenu = 0;
   
         int csysid;     /* For the s_flag. */          int csysid;     /* For the s_flag. */
         unsigned int cstart, csize;          unsigned int cstart, csize;
Line 342  main(int argc, char *argv[])
Line 400  main(int argc, char *argv[])
         i_flag = B_flag = 0;          i_flag = B_flag = 0;
         v_flag = 0;          v_flag = 0;
         E_flag = 0;          E_flag = 0;
         csysid = cstart = csize = 0;          csysid = -1;
           cstart = csize = ~0;
         while ((ch = getopt(argc, argv, OPTIONS)) != -1) {          while ((ch = getopt(argc, argv, OPTIONS)) != -1) {
                 switch (ch) {                  switch (ch) {
                 case '0':                  case '0':
Line 383  main(int argc, char *argv[])
Line 442  main(int argc, char *argv[])
                 case 'i':       /* Always update bootcode */                  case 'i':       /* Always update bootcode */
                         i_flag = 1;                          i_flag = 1;
                         break;                          break;
                   case 'I':       /* Ignore errors */
                           I_flag = 1;
                           break;
                 case 'l':       /* List known partition types */                  case 'l':       /* List known partition types */
                         for (len = 0; len < KNOWN_SYSIDS; len++)                          for (len = 0; len < KNOWN_SYSIDS; len++)
                                 printf("%03d %s\n", mbr_ptypes[len].id,                                  printf("%03d %s\n", mbr_ptypes[len].id,
Line 396  main(int argc, char *argv[])
Line 458  main(int argc, char *argv[])
                         break;                          break;
                 case 's':       /* Partition details */                  case 's':       /* Partition details */
                         s_flag = 1;                          s_flag = 1;
                         if (sscanf(optarg, "%d/%u/%u%n", &csysid, &cstart,  
                             &csize, &n) == 3) {                          if (parse_s(optarg, &csysid, &cstart, &csize,
                                 if (optarg[n] == 0)                              &cbootmenu) == -1)
                                         break;                                  errx(1, "Bad argument to the -s flag.");
 #ifdef BOOTSEL  
                                 if (optarg[n] == '/') {  
                                         cbootmenu = optarg + n + 1;  
                                         break;  
                                 }  
 #endif  
                         }  
                         errx(1, "Bad argument to the -s flag.");  
                         break;                          break;
                 case 'b':       /* BIOS geometry */                  case 'b':       /* BIOS geometry */
                         b_flag = 1;                          b_flag = 1;
Line 450  main(int argc, char *argv[])
Line 504  main(int argc, char *argv[])
                 case 'T':                  case 'T':
                         disk_type = optarg;                          disk_type = optarg;
                         break;                          break;
                   case 'z':
                           secsize = atoi(optarg);
                           if (secsize <= 512)
   out:                             errx(EXIT_FAILURE, "Invalid sector size %zd",
                                       secsize);
                           for (ch = secsize; (ch & 1) == 0; ch >>= 1)
                                   continue;
                           if (ch != 1)
                                   goto out;
                           break;
                 default:                  default:
                         usage();                          usage();
                 }                  }
Line 494  main(int argc, char *argv[])
Line 558  main(int argc, char *argv[])
         if (open_disk(B_flag || a_flag || i_flag || u_flag) < 0)          if (open_disk(B_flag || a_flag || i_flag || u_flag) < 0)
                 exit(1);                  exit(1);
   
           if (secsize > 512) {
                   if ((iobuf = malloc(secsize)) == NULL)
                           err(EXIT_FAILURE, "Cannot allocate %zd buffer",
                               secsize);
           }
   
         if (read_s0(0, &mboot))          if (read_s0(0, &mboot))
                 /* must have been a blank disk */                  /* must have been a blank disk */
                 init_sector0(1);                  init_sector0(1);
Line 600  usage(void)
Line 670  usage(void)
 {  {
         int indent = 7 + (int)strlen(getprogname()) + 1;          int indent = 7 + (int)strlen(getprogname()) + 1;
   
         (void)fprintf(stderr, "usage: %s [-afiluvBS] "          (void)fprintf(stderr, "usage: %s [-aBFfIilSuv] "
                 "[-A ptn_alignment[/ptn_0_offset]] \\\n"                  "[-A ptn_alignment[/ptn_0_offset]] \\\n"
                 "%*s[-b cylinders/heads/sectors] \\\n"                  "%*s[-b cylinders/heads/sectors] \\\n"
                 "%*s[-0123 | -E num "                  "%*s[-0123 | -E num "
                 "[-s id/start/size[/bootmenu]]] \\\n"                  "[-s [id][/[start][/[size][/bootmenu]]]] \\\n"
                 "%*s[-t disktab] [-T disktype] \\\n"                  "%*s[-t disktab] [-T disktype] \\\n"
                 "%*s[-c bootcode] "                  "%*s[-c bootcode] "
                 "[-r|-w file] [device]\n"                  "[-r|-w file] [device]\n"
                 "\t-a change active partition\n"                  "\t-a change active partition\n"
                 "\t-f force - not interactive\n"                  "\t-f force - not interactive\n"
                 "\t-i initialise MBR code\n"                  "\t-i initialise MBR code\n"
                   "\t-I ignore errors about no space or overlapping partitions\n"
                 "\t-l list partition types\n"                  "\t-l list partition types\n"
                 "\t-u update partition data\n"                  "\t-u update partition data\n"
                 "\t-v verbose output, -v -v more verbose still\n"                  "\t-v verbose output, -v -v more verbose still\n"
Line 687  print_s0(int which)
Line 758  print_s0(int which)
                         else                          else
                                 printf("First active partition: %d\n", active);                                  printf("First active partition: %d\n", active);
                 }                  }
                 if (!sh_flag && mboot.mbr_dsn != 0)                  if (!sh_flag)
                         printf("Drive serial number: %"PRIu32" (0x%08x)\n",                          printf("Drive serial number: %"PRIu32" (0x%08x)\n",
                             le32toh(mboot.mbr_dsn),                              le32toh(mboot.mbr_dsn),
                             le32toh(mboot.mbr_dsn));                              le32toh(mboot.mbr_dsn));
Line 1630  intuit_translated_geometry(void)
Line 1701  intuit_translated_geometry(void)
         }          }
   
         if (xheads == -1) {          if (xheads == -1) {
                   if (F_flag)
                           return;
                 warnx("Cannot determine the number of heads");                  warnx("Cannot determine the number of heads");
                 return;                  return;
         }          }
Line 1797  check_overlap(int part, int sysid, daddr
Line 1870  check_overlap(int part, int sysid, daddr
                         /* This is just a convention, not a requirement */                          /* This is just a convention, not a requirement */
                         return "Track zero is reserved for the BIOS";                          return "Track zero is reserved for the BIOS";
 #endif  #endif
                 if (start + size > disksectors)                  if (start + size > disksectors)
                         return "Partition exceeds size of disk";                          return "Partition exceeds size of disk";
                 for (p = 0; p < MBR_PART_COUNT; p++) {                  for (p = 0; p < MBR_PART_COUNT; p++) {
                         if (p == part || mboot.mbr_parts[p].mbrp_type == 0)                          if (p == part || mboot.mbr_parts[p].mbrp_type == 0)
Line 2007  change_part(int extended, int part, int 
Line 2080  change_part(int extended, int part, int 
                         tmp_bootmenu[0] = 0;                          tmp_bootmenu[0] = 0;
 #endif  #endif
   
         if (!s_flag && partp != NULL) {          if (partp != NULL) {
                 /* values not specified, default to current ones */                  if (!s_flag) {
                 sysid = partp->mbrp_type;                          /* values not specified, default to current ones */
                 start = offset + le32toh(partp->mbrp_start);                          sysid = partp->mbrp_type;
                 size = le32toh(partp->mbrp_size);                          start = offset + le32toh(partp->mbrp_start);
                           size = le32toh(partp->mbrp_size);
                   } else {
                           if (sysid == -1)
                                   sysid = partp->mbrp_type;
                           if (start == (daddr_t)0xffffffff) {
                                   start = offset + le32toh(partp->mbrp_start);
                                   if (start == 0)
                                           start = offset = ptn_0_offset;
                           }
                           if (size == (daddr_t)0xffffffff) {
                                   size = le32toh(partp->mbrp_size);
                                   if (size == 0)
                                           size = disksectors - start;
                           }
                   }
         }          }
   
         /* creating a new partition, default to free space */          /* creating a new partition, default to free space */
Line 2061  change_part(int extended, int part, int 
Line 2149  change_part(int extended, int part, int 
                                         p = -1;                                          p = -1;
                                 }                                  }
                         }                          }
                         if (start >= disksectors) {                          if (start >= disksectors && !I_flag) {
                                 printf("No free space\n");                                  printf("No free space\n");
                                 return 0;                                  return 0;
                         }                          }
Line 2156  change_part(int extended, int part, int 
Line 2244  change_part(int extended, int part, int 
                 errtext = check_ext_overlap(part, sysid, start, size, 0);                  errtext = check_ext_overlap(part, sysid, start, size, 0);
         else          else
                 errtext = check_overlap(part, sysid, start, size, 0);                  errtext = check_overlap(part, sysid, start, size, 0);
         if (errtext != NULL) {          if (errtext != NULL && !I_flag) {
                 if (f_flag)                  if (f_flag)
                         errx(2, "%s\n", errtext);                          errx(2, "%s\n", errtext);
                 printf("%s\n", errtext);                  printf("%s\n", errtext);
Line 2170  change_part(int extended, int part, int 
Line 2258  change_part(int extended, int part, int 
          * This also fixes the base of each extended partition if the           * This also fixes the base of each extended partition if the
          * partition itself has moved.           * partition itself has moved.
          */           */
           if (!I_flag) {
                   if (extended)
                           errtext = check_ext_overlap(part, sysid, start, size, 1);
                   else
                           errtext = check_overlap(part, sysid, start, size, 1);
                   if (errtext)
                           errx(1, "%s\n", errtext);
           }
   
         if (extended)  
                 errtext = check_ext_overlap(part, sysid, start, size, 1);  
         else  
                 errtext = check_overlap(part, sysid, start, size, 1);  
   
         if (errtext)  
                 errx(1, "%s\n", errtext);  
   
         if (sysid == 0) {          if (sysid == 0) {
                 /* delete this partition - save info though */                  /* delete this partition - save info though */
Line 2303  print_geometry(void)
Line 2392  print_geometry(void)
         printf("Disk: %s\n", disk);          printf("Disk: %s\n", disk);
         printf("NetBSD disklabel disk geometry:\n");          printf("NetBSD disklabel disk geometry:\n");
         printf("cylinders: %d, heads: %d, sectors/track: %d "          printf("cylinders: %d, heads: %d, sectors/track: %d "
             "(%d sectors/cylinder)\ntotal sectors: %"PRIdaddr"\n\n",              "(%d sectors/cylinder)\ntotal sectors: %"PRIdaddr", "
             cylinders, heads, sectors, cylindersectors, disksectors);              "bytes/sector: %zd\n\n", cylinders, heads, sectors,
               cylindersectors, disksectors, secsize);
         printf("BIOS disk geometry:\n");          printf("BIOS disk geometry:\n");
         printf("cylinders: %d, heads: %d, sectors/track: %d "          printf("cylinders: %d, heads: %d, sectors/track: %d "
             "(%d sectors/cylinder)\ntotal sectors: %"PRIdaddr"\n\n",              "(%d sectors/cylinder)\ntotal sectors: %"PRIdaddr"\n\n",
Line 2462  open_disk(int update)
Line 2552  open_disk(int update)
         return (0);          return (0);
 }  }
   
 static int  static ssize_t
 read_disk(daddr_t sector, void *buf)  read_disk(daddr_t sector, void *buf)
 {  {
           ssize_t nr;
   
         if (*rfd == -1)          if (*rfd == -1)
                 errx(1, "read_disk(); fd == -1");                  errx(1, "read_disk(); fd == -1");
         if (lseek(*rfd, sector * (off_t)512, 0) == -1)  
                 return (-1);  
         return (read(*rfd, buf, 512));  
 }  
   
 static int          off_t offs = sector * (off_t)secsize;
           off_t mod = offs & (secsize - 1);
           off_t rnd = offs & ~(secsize - 1);
   
           if (lseek(*rfd, rnd, SEEK_SET) == (off_t)-1)
                   return -1;
   
           if (secsize == 512)
                   return read(*rfd, buf, 512);
   
           if ((nr = read(*rfd, iobuf, secsize)) != secsize)
                   return nr;
   
           memcpy(buf, &iobuf[mod], 512);
   
           return 512;
   }
   
   static ssize_t
 write_disk(daddr_t sector, void *buf)  write_disk(daddr_t sector, void *buf)
 {  {
           ssize_t nr;
   
         if (wfd == -1)          if (wfd == -1)
                 errx(1, "write_disk(); wfd == -1");                  errx(1, "write_disk(); wfd == -1");
         if (lseek(wfd, sector * (off_t)512, 0) == -1)  
                 return (-1);          off_t offs = sector * (off_t)secsize;
         return (write(wfd, buf, 512));          off_t mod = offs & (secsize - 1);
           off_t rnd = offs & ~(secsize - 1);
   
           if (lseek(wfd, rnd, SEEK_SET) == (off_t)-1)
                   return -1;
   
           if (secsize == 512)
                   return write(wfd, buf, 512);
   
           if ((nr = read(wfd, iobuf, secsize)) != secsize)
                   return nr;
   
           if (lseek(wfd, rnd, SEEK_SET) == (off_t)-1)
                   return -1;
   
           memcpy(&iobuf[mod], buf, 512);
   
           if ((nr = write(wfd, iobuf, secsize)) != secsize)
                   return nr;
   
           return 512;
 }  }
   
 static void  static void
Line 2522  get_params(void)
Line 2648  get_params(void)
                 guess_geometry(disklabel.d_secperunit);                  guess_geometry(disklabel.d_secperunit);
                 disklabel.d_ncylinders = dos_cylinders;                  disklabel.d_ncylinders = dos_cylinders;
                 disklabel.d_ntracks = dos_heads;                  disklabel.d_ntracks = dos_heads;
                   disklabel.d_secsize = 512;
                 disklabel.d_nsectors = dos_sectors;                  disklabel.d_nsectors = dos_sectors;
         } else if (ioctl(fd, DIOCGDEFLABEL, &disklabel) == -1) {          } else if (ioctl(fd, DIOCGDEFLABEL, &disklabel) == -1) {
                 warn("DIOCGDEFLABEL");                  warn("DIOCGDEFLABEL");
Line 2534  get_params(void)
Line 2661  get_params(void)
         disksectors = disklabel.d_secperunit;          disksectors = disklabel.d_secperunit;
         cylinders = disklabel.d_ncylinders;          cylinders = disklabel.d_ncylinders;
         heads = disklabel.d_ntracks;          heads = disklabel.d_ntracks;
           secsize = disklabel.d_secsize;
         sectors = disklabel.d_nsectors;          sectors = disklabel.d_nsectors;
   
         /* pick up some defaults for the BIOS sizes */          /* pick up some defaults for the BIOS sizes */
Line 2619  read_s0(daddr_t offset, struct mbr_secto
Line 2747  read_s0(daddr_t offset, struct mbr_secto
                 return -1;                  return -1;
         }          }
         if (boot->mbr_magic != LE_MBR_MAGIC) {          if (boot->mbr_magic != LE_MBR_MAGIC) {
                   if (F_flag && boot->mbr_magic == 0)
                           return -1;
                 warnx("%s partition table invalid, "                  warnx("%s partition table invalid, "
                     "no magic in sector %"PRIdaddr, tabletype, offset);                      "no magic in sector %"PRIdaddr, tabletype, offset);
                 return -1;                  return -1;
Line 2717  yesno(const char *str, ...)
Line 2847  yesno(const char *str, ...)
         va_list ap;          va_list ap;
   
         va_start(ap, str);          va_start(ap, str);
   
         vprintf(str, ap);          vprintf(str, ap);
           va_end(ap);
         printf(" [n] ");          printf(" [n] ");
   
         first = ch = getchar();          first = ch = getchar();

Legend:
Removed from v.1.134  
changed lines
  Added in v.1.134.2.4

CVSweb <webmaster@jp.NetBSD.org>