verify_diskette.c

Upload User: acmefrp
Upload Date: 2010-03-06
Package Size: 23768k
Code Size: 8k
Category: OS Develop
Development Platform: C/C++
  1. #ifdef lint
  2. #ident "@(#)verify_diskette.c 1.1 92/07/30 SMI";
  3. #endif
  4. /*
  5.  *
  6.  * verify_diskette - to verify that the floppy in the drive is the right one
  7.  * for suninstall.  All error messages and prompts go to stderr.
  8.  *
  9.  *  verify_diskette arch volno archieveno mediadev name [mediaserver]
  10.  *
  11.  * argv[0] - cmdname
  12.  * argv[1] - arch or "-" allowed if just reading a toc
  13.  * argv[2] - volume number or "-1" to say just reading a toc
  14.  * argv[3] - archieveno - which file on tape / offset of file on floppy
  15.  * argv[4] - install media device
  16.  * argv[5] - "name" - IGNORED
  17.  * [ argv[6] - mediaserver - since diskettes can`t be remote : NOT USED! ]
  18.  */
  19. /*
  20.  * Assumptions:
  21.  *
  22.  * o On diskette, each suninstall catagory is a compressed tar(1) format
  23.  *   file that is dd'd onto the diskette(s).  It starts at the volume
  24.  *   number given in the xdrtoc, which is passed into this code.
  25.  *   (It starts at an offset, which is passed in as the "archieveno",
  26.  *   but this script doesn't need to use it).
  27.  *   NOTE: the tar file may cross diskettes, so this program must handle
  28.  *   that, verifying in turn that each particular volume is mounted.
  29.  *   This program checks the "suninstall label" aka "label", which is
  30.  *   an ascii string of the form:
  31.  * Volume ## of <Application SunOS - or other text> for ARCH
  32.  * where:
  33.  * ## is a decimal number
  34.  * ARCH is "sun4c" or other Sun arch string
  35.  *
  36.  */
  37. /*
  38.  * NOTE: this file serves both as source for itself, and as the subroutines
  39.  * for extracting diskette - as set off by ifdef SUBROUTINE_ONLY
  40.  * (the subroutines come first)
  41.  */
  42. #include <errno.h>
  43. #include <stdio.h>
  44. #include <fcntl.h>
  45. #include <sys/types.h>
  46. #include <sun/dkio.h>
  47. #include "install.h" /* LOGFILE is a char[] from strings.o */
  48. #ifndef SUBROUTINE_ONLY /* so extracting_diskette can use subs */
  49. char *progname = "verify_diskette";
  50. #endif !SUBROUTINE_ONLY
  51. /* media size is set to 79 * 18 * 2 * 512 bytes! HARDCODED */
  52. /* FIX ME : use DKIOCGAPART */
  53. int disksize = 1456128;
  54. #define XDRSIZE (512*(36-(4+1)))
  55. #define CYLSIZE (512*36)
  56. #define VLBLOFFSET (35*512) /* offset of per volume label */
  57. #define XDRTOCOFFSET (4*512) /* offset of xdrtoc on diskette */
  58. #define VLBLSIZE 512
  59. char msg[512]; /* for error messages, etc. */
  60. FILE *logf = NULL;
  61. char vlbljunk[100];
  62. int vlblvol;
  63. char vlblarch[100];
  64. char *nullstring = "";
  65. char buf[ CYLSIZE ]; /* for diskette, and input responses */
  66. char cyl1dev[50];
  67. char mediadev[50];
  68. /*
  69.  * verify that the correct diskette is in the drive
  70.  */
  71. verify_diskette(device, volnum, arch)
  72. char *device;
  73. int volnum;
  74. char *arch;
  75. {
  76. int fd;
  77. int chgd;
  78. /*
  79.  * first read the diskette mini label off to see which one this is
  80.  * and if it is of the correct set.
  81.  * O_NDELAY is set so we don't touch the disk just yet
  82.  */
  83. if ((fd = open(device, O_RDONLY|O_NDELAY)) < 0) {
  84. sprintf(msg,
  85.     "%s: fatal error: can't open %s", progname, cyl1dev);
  86. domsg(0);
  87. exit(1);
  88. }
  89. while (1) {
  90. /* verify diskette in drive */
  91. if (ioctl(fd, FDKGETCHANGE, &chgd) != 0) {
  92. sprintf(msg, "%s: fatal error on FDKGETCHANGE of %sn",
  93.     progname, cyl1dev);
  94. domsg(0);
  95. exit(1);
  96. }
  97. /* if disk changed is currently clear, a diskette is in drive */
  98. if ((chgd & FDKGC_CURRENT) != 0) {
  99. sprintf(msg, "NO DISKETTE IN DRIVEn");
  100. goto ask_for_another;
  101. }
  102. /* seek to where the vol label is */
  103. if (lseek(fd, VLBLOFFSET, 0) != VLBLOFFSET) {
  104. sprintf(msg, "%s: fatal error: couldn't seek on %s",
  105.     progname, cyl1dev);
  106. domsg(0);
  107. exit(1);
  108. } else
  109. if (read(fd, buf, VLBLSIZE) != VLBLSIZE) {
  110. sprintf(msg, "%s: couldn't read %s", progname, cyl1dev);
  111. domsg(0);
  112. } else
  113. if (grabscan(buf)) {
  114. sprintf(msg,
  115. "%s: bad scan of label: not a suninstall diskette?n",
  116.     progname);
  117. domsg(0);
  118. } else if ((((volnum == -1) && (*arch != '-')) ||
  119.     (volnum != -1)) &&
  120.     (strcmp(arch, vlblarch) != 0)) {
  121. sprintf(msg, "%s: diskette arch "%s" is not "%s"n",
  122. progname, vlblarch, arch);
  123. domsg(0);
  124. } else
  125. /* if only checking for one with a toc, don`t check volume */
  126. if ((volnum != -1) && (volnum != vlblvol)) {
  127. sprintf(msg, "%s: diskette number %d is not %dn",
  128. progname, vlblvol, volnum);
  129. domsg(0);
  130. } else
  131. /*
  132.  * we got here with the correct diskette - but we need to
  133.  * parse the xdrtoc for the starting offset and size
  134.  * (or send it to std out if volnum == -1)
  135.  */
  136. /* go to where xdrtoc resides */
  137. if (lseek(fd, XDRTOCOFFSET, 0) != XDRTOCOFFSET) {
  138. sprintf(msg, "%s: fatal error: couldn't seek on %s",
  139.     progname, cyl1dev);
  140. domsg(0);
  141. exit(1);
  142. } else
  143. if (read(fd, buf, XDRSIZE) != XDRSIZE) {
  144. sprintf(msg, "%s: couldn't read %s", progname, cyl1dev);
  145. domsg(0);
  146. } else {
  147. break;
  148. }
  149. /* if we get here, we failed a check, so eject the floppy */
  150. (void)ioctl(fd, FDKEJECT, NULL);
  151. /* ask (as precisely as possible) user to put in a diskette */
  152. msg[0] = '';
  153. ask_for_another:
  154. if (volnum == -1) {
  155. sprintf(&msg[strlen(msg)],
  156.     "insert any suninstall diskette");
  157. if (*arch != '-')
  158. sprintf(&msg[strlen(msg)], " for "%s"", arch);
  159. } else {
  160. sprintf(&msg[strlen(msg)],
  161.     "insert suninstall diskette %d for "%s"",
  162.     volnum, arch);
  163. }
  164. sprintf(&msg[strlen(msg)], ", then press <return>:");
  165. domsg(1);
  166. continue;
  167. }
  168. if (volnum == -1)
  169. (void)write(1, buf, XDRSIZE);
  170. close(fd);
  171. return (0);
  172. }
  173. /*
  174.  * parse the buffer for strings (all builtin)
  175.  */
  176. grabscan(buf)
  177. char *buf;
  178. {
  179. char *sp;
  180. int expect;
  181. int x;
  182. char *strtok();
  183. expect = 2;
  184. sp = buf;
  185. while ((sp = strtok(sp, " n")) != NULL) {
  186. x = sscanf(sp, "volume=%d", &vlblvol);
  187. if (x == 1) {
  188. expect--;
  189. }
  190. x = sscanf(sp, "arch=%s", vlblarch);
  191. if (x == 1) {
  192. expect--;
  193. }
  194. sp = NULL; /* arm strtok() for next pass */
  195. }
  196. return (expect);
  197. }
  198. domsg(flg)
  199. int flg; /* 0 just print, 1 = wait for return */
  200. {
  201. fprintf(stderr, msg);
  202. if (logf == NULL) {
  203. /* if we can't open the log file, just tuff! */
  204. logf = fopen(LOGFILE, "a");
  205. }
  206. if (logf != NULL)
  207. fprintf(logf, msg);
  208. if (flg) {
  209. /* wait for user to type a return */
  210. /* (void)fgets(buf, 512, stdin); */
  211. while (1) {
  212. (void) read(0, buf, 1);
  213. if ((buf[0] == 'n') || (buf[0] == 'r'))
  214. break;
  215. }
  216. if (logf != NULL)
  217. fprintf(logf, "n");
  218. }
  219. }
  220. /*
  221.  * get_mediadev - parse input for correct media device and forces it
  222.  * to partition "a"
  223.  */
  224. void
  225. get_mediadev(cp)
  226. char *cp;
  227. {
  228. strcpy(mediadev, cp);
  229. /* find the unit number in the string */
  230. /* ASSUMES its the only numeric in the string XXX */
  231. cp = mediadev;
  232. while ((*cp != '0') && (*cp != '1'))
  233. cp++;
  234. cp++; /* jump over the unit number */
  235. *cp++ = 'a'; /* tack on a "a" for suninstall data partition */
  236. *cp = ''; /* and end string nicely */
  237. }
  238. #ifndef SUBROUTINE_ONLY /* so extracting_diskette can use subs */
  239. int volnum;
  240. int xdrvol;
  241. int xdroffset;
  242. char xdrname[100];
  243. int xdrcount;
  244. /* the args */
  245. char *cmdname; /* 0 */
  246. char *arch; /* 1 */
  247. char *volno; /* 2 */
  248. char *archieveno; /* 3 */
  249. /* char *mediadev; 4 */
  250. /* char *name; 5 */
  251. /* char *mediaserver; 6 */
  252. main(argc, argv)
  253. int argc;
  254. char **argv;
  255. {
  256. int fd;
  257. int chgd;
  258. char *cp;
  259. if ((argc < 6) || (argc > 7)) {
  260. sprintf(msg,
  261. "Usage: %s [arch|-] [volno|-1] offset mediadev name [mediaserver]n",
  262.     argv[0]);
  263. domsg(0);
  264. exit(1);
  265. }
  266. if ((argc == 7) && (*argv[6] != '')) {
  267. sprintf(msg,
  268. "ERROR: remote diskette installation not supported...press <RETURN>");
  269. domsg(1);
  270. exit(1);
  271. }
  272. cmdname = argv[ 0 ];
  273. arch = argv[ 1 ];
  274. volno = argv[ 2 ];
  275. archieveno = argv[ 3 ];
  276. get_mediadev(argv[ 4 ]);
  277. if ((volnum = atoi(volno)) == 0) {
  278. sprintf(msg, "%s: invalid volume number, volno arg was %sn",
  279.     progname, volno);
  280. domsg(0);
  281. exit(1);
  282. }
  283. /* *** cyl1dev=`expr X$mediadev : 'X(.*fd[0-1]).*'` *** */
  284. /* *** cyl1dev=${cyl1dev}b *** */
  285. strcpy(cyl1dev, mediadev);
  286. cp = cyl1dev;
  287. /* find the unit number in the string */
  288. while ((*cp != '0') && (*cp != '1'))
  289. cp++;
  290. cp++; /* jump over the unit number */
  291. *cp++ = 'b'; /* tack on a "b" for label partition */
  292. *cp = ''; /* and end string nicely */
  293. verify_diskette(cyl1dev, volnum, arch);
  294. exit(0);
  295. }
  296. #endif !SUBROUTINE_ONLY