rtinit.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 578 行
C
578 行
#ifndef lintstatic char *sccsid = "@(#)rtinit.c 4.1 (ULTRIX) 7/2/90";#endif lint/************************************************************************ * * * Copyright (c) 1984 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//*FACILITY: RT-11 volume manipulation.ABSTRACT: Initialize an RT-11 device.ENVIRONMENT: PRO/VENIX user mode. ULTRIX-11 user mode. ULTRIX-32 user mode.AUTHOR: Brian Hetrick, CREATION DATE: 1 March 1985.MODIFIED BY: Brian Hetrick, 01-Mar-85: Version 1.0 000 - Original version of module.*//* * INCLUDE FILES: */#include "arff.h"#include <stdio.h>#include <ctype.h>/* * TABLE OF CONTENTS: *//* * MACROS: *//* * EQUATED SYMBOLS: *//* * OWN STORAGE: */static uword segtab [5] = {640, 1280, 2560, 5120, 10240};/* * EXTERNAL REFERENCES: */extern arcpad (), /* Copy and blank pad a string. */ arwcmt (), /* Notify of "wild card" match. */ exit (), /* Terminate program. */ fprintf (), /* Print message to file. */ rtidep (), /* Increment directory entry pointer. */ rtopen (), /* Open RT-11 device. */ rtputb (), /* Write a block. */ rtputs (); /* Write a directory segment. */extern char * strcpy (); /* Copy string. */extern int arvfyn (), /* Verify action with user. */ strlen (); /* Find length of string. */extern char * pgmnam; /* Program's name. */extern int modflg; /* Action modifier flags. */extern struct homblk homblk; /* Device home block. */extern struct dirseg dirseg; /* First directory segment. */rtinit (filc, filv)int filc;char * * filv;/*********************************************************************FUNCTIONAL DESCRIPTION: Initializes an RT-11 volume.FORMAL PARAMETERS: File_count.rg.v - A count of the number of arguments. File_vector.rt.ra - The arguments. The one and only element of File_vector is a comma separated list of options to use when initializing the RT-11 volume. The first (mandatory) item is a decimal digit string whose numeric value is the number of blocks in the RT-11 volume. The second (optional) item is a decimal digit string whose numeric value is the number of directory segments in the RT-11 volume. The third (optional) item is a character string whose value is the volume identifi- cation. The fourth (optional) item is a character string whose value is the volume owner. The fifth (optional) item is a decimal digit string whose numeric value is the number of extra words in each directory entry. Items in the option list may be omitted by putting nothing between the delimiting commas or the delimiting comma and the end of the option string. Trailing commas need not be specified.IMPLICIT INPUTS: modflg - The action modifier flags.IMPLICIT OUTPUTS: homblk - The RT-11 volume home block. dirseg - The directory segment buffer.ROUTINE VALUE: None.SIDE EFFECTS: Initializes the RT-11 volume. May exit with an error message.*********************************************************************/{ static char msg1 [] = "%s: Illegal conversion, number of %s\n", msg2 [] = "%s: Truncated to 12 characters, %s\n", msg3 [] = "%s: Range error, number of %s\n"; char inchar, /* Character from option string. */ * inptr, /* Pointer into option string. */ * outptr, /* Pointer into volume id/owner string. */ volid [13], /* Volume identification. */ owner [13]; /* Volume owner name. */ long numblk; /* Number of blocks in RT-11 volume. */ uword numext, /* Number of extra words in dir segment. */ numseg; /* Number of directory segments. */ int i, /* General counter. */ trunc; /* String truncation flag. */ struct dirent * de_ptr; /* Directory entry pointer. */ /* * Check arguments. */ if (filc != 1) { fprintf (stderr, "%s: Wrong number of arguments for initialize\n", pgmnam); exit (1); } /* * Get values from argument. */ inptr = * filv; arwcmt (0); /* * Get number of blocks in RT-11 volume. */ numblk = 0; while (('\0' != (inchar = * inptr ++)) && (',' != inchar)) { if (! isdigit (inchar)) { fprintf (stderr, msg1, pgmnam, "blocks"); exit (1); } numblk *= 10; numblk += (inchar - '0'); } /* * Get number of directory segments. */ if ('\0' == inchar) { numseg = 0; } else { numseg = 0; while (('\0' != (inchar = * inptr ++)) && (',' != inchar)) { if (! isdigit (inchar)) { fprintf (stderr, msg1, pgmnam, "directory segments"); exit (1); } numseg *= 10; numseg += (inchar - '0'); } } /* * Get volume identification. */ if ('\0' == inchar) { volid [0] = '\0'; } else { i = 12; trunc = 0; outptr = & volid [0]; while (('\0' != (inchar = * inptr ++)) && (',' != inchar)) { if (i <= 0) { trunc = 1; } else { * outptr ++ = inchar; } i --; } * outptr = '\0'; if (trunc) { fprintf (stderr, msg2, pgmnam, "volume ID"); } } /* * Get volume owner. */ if ('\0' == inchar) { owner [0] = '\0'; } else { i = 12; trunc = 0; outptr = & owner [0]; while (('\0' != (inchar = * inptr ++)) && (',' != inchar)) { if (i <= 0) { trunc = 1; } else { * outptr ++ = inchar; } i --; } * outptr = '\0'; if (trunc) { fprintf (stderr, msg2, pgmnam, "owner"); } } /* * Get number of extra words per directory segment. */ if ('\0' == inchar) { numext = 0; } else { numext = 0; while ('\0' != (inchar = * inptr ++)) { if (! isdigit (inchar)) { fprintf (stderr, msg1, pgmnam, "extra words"); exit (1); } numext *= 10; numext += (inchar - '0'); } } /* * Validity check and apply defaults. */ if ((numblk < 9l) || (65535l < numblk)) { fprintf (stderr, msg3, pgmnam, "blocks"); exit (1); } if (0 == numseg) { numseg = 31; for (i = 0; i < 5; i ++) { if (numblk <= segtab [i]) { numseg = (uword) (1 << i); break; } } } else { if (31 < numseg) { fprintf (stderr, msg3, pgmnam, "directory segments"); exit (1); } } if (0 == strlen (volid)) { strcpy (volid, "RT11A"); } if (numext > 500) { fprintf (stderr, msg3, pgmnam, "extra words"); exit (1); } /* * Report parameters. */ if (modflg & FLG_VERB) { printf ("Number of blocks in device: %ld\n", numblk); printf ("Number of directory segments: %u\n", numseg); printf ("Volume ID: %s\n", volid); printf ("Owner: %s\n", owner); printf ("Extra words in directory entry: %u\n\n", numext); } /* * Inquire whether to really initialize. */ if (! arvfyn ("ALL DATA ON VOLUME WILL BE DESTROYED\nReally initialize? ")) { return; } /* * Will need to write/create the RT-11 device. */ rtopen (ACC_CREA); /* * Rebuild home block. */#ifdef DEBUG fprintf (stderr, "Rebuilding home block\n");#endif for (outptr = (char *) (& homblk), i = 510; i > 0; i --) { * outptr ++ = '\0'; } homblk.hb_clus = 1; /* Cluster size. */ homblk.hb_dirs = DIRSEG1; /* First directory segment. */ homblk.hb_sysv = 0107351; /* System version: RAD 50 "V3A" */ arcpad (homblk.hb_voli, volid, 12); /* Volume ID */ arcpad (homblk.hb_owne, owner, 12); /* Owner name */ arcpad (homblk.hb_sysi, "DEC ULTRIX", 12); /* System ID */ trunc = 0; for (i = 0, inptr = (char *) (& homblk); i < 510; i ++) { trunc += (* inptr ++); } homblk.hb_chec = trunc; /* Checksum. */#ifdef DEBUG fprintf (stderr, "Writing new home block\n");#endif rtputb ((uword) HOMBLK, (char *) (& homblk)); /* * Rebuild directory segment 1. */#ifdef DEBUG fprintf (stderr, "Rebuilding directory segment 1.\n");#endif dirseg.ds_nseg = numseg; /* Number segments total. */ dirseg.ds_next = 0; /* Next segment number. */ dirseg.ds_hseg = 1; /* Highest segment used. */ dirseg.ds_xtra = numext; /* Extra words. */ dirseg.ds_sblk = /* Start of data area. */ (uword) DIRSEG1 + (uword) 2 * numseg; de_ptr = (struct dirent *) (& dirseg.ds_dent [0]); de_ptr -> de_stat = DE_EMPT; /* Type: empty. */ de_ptr -> de_nblk = /* Number of free blocks. */ numblk - dirseg.ds_sblk; rtidep (& dirseg, & de_ptr); de_ptr -> de_stat = DE_ENDS; /* Type: end segment. */#ifdef DEBUG fprintf (stderr, "Writing new directory segment 1\n");#endif rtputs (1, (char *) (& dirseg)); /* * That is it. */}/* rtboot performs rtboot magic for a real rt-11 console storage device *//* lp@decvax */#include <sys/file.h>char sradname[20];rtboot( cnt, files)int cnt;char **files;{ char *monsrc[2]; char *index(); int mondes, bootdes;/* The defaults *//* monsrc[0] = "rt11fb.sys"; monsrc[1] = "dl.sys"; */ if(cnt == 2) { monsrc[0] = *files++; monsrc[1] = *files; } else { fprintf(stderr, "Must specify monitor & handler files\n"); exit (0); }/* } else if (cnt == 1) monsrc[1] = *files; */ if (modflg & FLG_EXTR) { rtextr(2, monsrc); /* extract does an open on rl02 */ rtclos(); /* so close it */ if (modflg & FLG_VERB) printf("Extracted %s & %s\n", monsrc[0], monsrc[1]); } strncpy(&sradname[0], monsrc[0], index(monsrc[0],'.') - monsrc[0]); if ((mondes = open(monsrc[0], O_RDONLY, 0)) < 0) { printf("error opening monitor file %s\n", monsrc[0]); exit (0); } if ((bootdes = open(monsrc[1], O_RDONLY, 0)) < 0) { printf("error opening primary boot file %s\n", monsrc[1]); exit (0); } if(!rwbootb(mondes, bootdes)) printf("error reading monitor file or primary boot file\n"); if (modflg & FLG_VERB) printf("Boot block update done\n"); exit (1);}#define BLKSZ 512int bldboot = 0;rwbootb(monitor, handler)int monitor, handler;{ char driver[BLKSZ], blockm[4][BLKSZ]; struct bb { short tmp1[25]; short of1; short tmp[230]; } blockb; int offset = 0, cnt; if(read(handler, &blockb, BLKSZ) != BLKSZ) return (0); (void) lseek (monitor, 512L, 0); /* Skip 1st block */ for (cnt = 0; cnt < 5; cnt++) if(read(monitor, &blockm[cnt][0], BLKSZ) != BLKSZ) /* Read next 4 */ return (0); arar50(&sradname[0], &blockm[3][0724], strlen(&sradname[0]));#ifdef lp printf("offset to primary driver = %d\n", blockb.of1);#endif offset = lseek (handler,(long) blockb.of1, 0); /* May only get a partial read here */ if((cnt = read(handler, driver, BLKSZ)) != BLKSZ) cnt += read(handler, driver+cnt, BLKSIZ - cnt); bldboot++; rtopen(ACC_WRIT); rtputb(0, driver); rtputb ((uword) HOMBLK, (char *) (& homblk)); for(cnt = 2; cnt < 6; cnt++) rtputb(cnt, &blockm[cnt - 2][0]); rtclos(); return (1);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?