141 lines
3.0 KiB
C
141 lines
3.0 KiB
C
|
/* This file contains some code to guess where we have to load the
|
||
|
* RAM image device from, if started from CD. (In this case it's hard
|
||
|
* to tell where this is without diving into BIOS heuristics.)
|
||
|
*
|
||
|
* There is some nasty hard-codery in here ( MINIX cd label) that can be
|
||
|
* improved on.
|
||
|
*
|
||
|
* Changes:
|
||
|
* Jul 14, 2005 Created (Ben Gras)
|
||
|
* Feb 10, 2006 Changed into a standalone program (Philip Homburg)
|
||
|
*/
|
||
|
|
||
|
#define CD_SECTOR 2048
|
||
|
#define SUPER_OFF 1024
|
||
|
#define AT_MINORS 8
|
||
|
#define MAGIC_OFF 24
|
||
|
|
||
|
#include <errno.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#include "mfs/const.h"
|
||
|
|
||
|
char pvd[CD_SECTOR];
|
||
|
|
||
|
/*===========================================================================*
|
||
|
* cdprobe *
|
||
|
*===========================================================================*/
|
||
|
int main(void)
|
||
|
{
|
||
|
int controller, disk, r, fd, minor, found;
|
||
|
off_t pos;
|
||
|
u16_t *magicp;
|
||
|
char name1[]= "/dev/c0dX";
|
||
|
char name2[]= "/dev/c0dXpY";
|
||
|
int probelist[AT_MINORS] = { 2, 3, 1, 0, 6, 7, 5, 4 };
|
||
|
|
||
|
found= 0;
|
||
|
for(controller = 0; controller <= 1; controller++) {
|
||
|
name1[6] = '0' + controller;
|
||
|
name2[6] = '0' + controller;
|
||
|
for(disk = 0; disk < AT_MINORS; disk++) {
|
||
|
name1[8]= '0' + probelist[disk];
|
||
|
|
||
|
fprintf(stderr, "Trying %s \r", name1);
|
||
|
fflush(stderr);
|
||
|
|
||
|
fd = open(name1, O_RDONLY);
|
||
|
if (fd < 0)
|
||
|
{
|
||
|
if (errno != ENXIO)
|
||
|
{
|
||
|
fprintf(stderr, "open '%s' failed: %s\n",
|
||
|
name1, strerror(errno));
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
pos= lseek(fd, 16*CD_SECTOR, SEEK_SET);
|
||
|
if (pos != 16*CD_SECTOR)
|
||
|
{
|
||
|
/* Strange, do we need to issue a warning? */
|
||
|
close(fd);
|
||
|
continue;
|
||
|
}
|
||
|
r = read(fd, pvd, sizeof(pvd));
|
||
|
if (r != sizeof(pvd))
|
||
|
{
|
||
|
fprintf(stderr,
|
||
|
"error reading CD label from '%s': %s\n",
|
||
|
name1, strerror(errno));
|
||
|
close(fd);
|
||
|
continue;
|
||
|
}
|
||
|
close(fd);
|
||
|
|
||
|
/* Check PVD ID. */
|
||
|
if (pvd[0] != 1 || pvd[1] != 'C' || pvd[2] != 'D' ||
|
||
|
pvd[3] != '0' || pvd[4] != '0' || pvd[5] != '1' ||
|
||
|
pvd[6] != 1 ||
|
||
|
strncmp(pvd + 40, "MINIX", 5) != 0) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* 3. Both cXdYp1 and p2 should have a superblock. */
|
||
|
found= 1; /* Assume everything is okay */
|
||
|
for (minor = 1; minor <= 2; minor++) {
|
||
|
name2[8]= '0' + probelist[disk];
|
||
|
name2[10]= '0' + minor;
|
||
|
|
||
|
fd = open(name2, O_RDONLY);
|
||
|
if (fd < 0)
|
||
|
{
|
||
|
if (errno != ENXIO)
|
||
|
{
|
||
|
fprintf(stderr,
|
||
|
"open '%s' failed: %s\n",
|
||
|
name2, strerror(errno));
|
||
|
}
|
||
|
found= 0;
|
||
|
break;
|
||
|
}
|
||
|
r = read(fd, pvd, sizeof(pvd));
|
||
|
if (r != sizeof(pvd))
|
||
|
{
|
||
|
fprintf(stderr,
|
||
|
"error reading super block from '%s': %s\n",
|
||
|
name2, strerror(errno));
|
||
|
close(fd);
|
||
|
found= 0;
|
||
|
break;
|
||
|
}
|
||
|
close(fd);
|
||
|
|
||
|
magicp= (u16_t *)&pvd[SUPER_OFF+MAGIC_OFF];
|
||
|
if (*magicp != SUPER_V3)
|
||
|
{
|
||
|
fprintf(stderr, "bad super block on %s\n",
|
||
|
name2);
|
||
|
found= 0;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (found)
|
||
|
{
|
||
|
fprintf(stderr, "\nFound.\n");
|
||
|
printf("%s\n", name1);
|
||
|
exit(0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
fprintf(stderr, "\nNot found.\n");
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|