putfile.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,538 行 · 第 1/3 页
C
1,538 行
#ifndef lintstatic char *sccsid = "@(#)putfile.c 4.1 (ULTRIX) 7/17/90";#endif lint/**************************************************************** * * * Copyright (c) 1985 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. * * * ****************************************************************//**//* * * File name: * * putfile.c * * Source file description: * * This file contains the logic to put * individual files on an output volume for * the Labeled Tape Facility (LTF). * * * Functions: * * bflush() Flushes Fortran Unformatted File * record buffer data to output * volume. * * addrtyp() ?_? Used during Fortran Formatted * File output record processing. * * append() Appends (writes) the current * file to the output volume. * * process() The function that actually * writes the ANSI file header * and ANSI file trailer * records on the output volume. * * putfile() Determines the "type" of file * being put on the output volume * and calls function "process" to * cause the file to be output. * * Usage: * * n/a * * Compile: * * cc -O -c putfile.c <- For Ultrix-32/32m * * cc CFLAGS=-DU11-O putfile.c <- For Ultrix-11 * * * Modification history: * ~~~~~~~~~~~~~~~~~~~~ * * revision comments * -------- ----------------------------------------------- * 01.0 2-May-85 Ray Glaser * Create original version. * * 01.1 10-Sep-85 Suzanne Logcher * Add logic to detect current century * * 01.2 24-Sep-85 Suzanne Logcher * Add logic to treat directory and subdirectory * entries using ../ or ./ as relative pathnames * * 01.3 31-Oct-85 Suzanne Logcher * Add logic to create segmented files * * 01.4 25-Mar-87 Suzanne Logcher * Removed the declaration of Inbuf from * process() because it was not on a word * boundary needed for some tape drives. * Now is called Outbuf and is global. *//* * +--> Local Includes */#include "ltfdefs.h"char *rindex();/**//* * * Function: * * bflush * * Function Description: * * Flushes (writes to output volume) the Fortran * Unformatted File record buffer. * * Arguments: * * char *name filename used when error in write * char *Outbuf file writing buffer * * Return values: * * none * * Side Effects: * * Data is written to the output volume from the * and the blocks written count is updated. */bflush(name, Outbuf) char *name; /* filename */ char *Outbuf; /* File writing buffer */{if (Rb - Bb > 0) { while (Rb < Bb + Blocksize) *Rb++ = PAD; if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) { PERROR "\n%s: %s %s\n", Progname, ERRWRF, name); perror(Magtdev); ceot(); } Blocks++;}}/*E bflush() *//**//* * * Function: * * addrtyp * * Function Description: * * Used during output to a volume for Fortran * Unformatted File proccessing ?_? * * Arguments: * * char *inch ?_? * char *typ ?_? * * * Return values: * * none * * Side Effects: * * not known at this time */addrtyp(inch, typ) char *inch; char *typ;{inch[4] = typ[0];inch[5] = typ[1];}/*E addrtyp() *//**//* * * Function: * * append * * Function Description: * * Appends (writes) the given file to the output volume. * * Arguments: * * char *name filename * FILE *fp Pointer to file to output * int max Maximum line length * int type Type of ANSI tape file being output * int tftype True file type of file being output * char *Outbuf File writing buffer * * Return values: * * Returns a LONG count of number of blocks output. * * Returns -1 and -2 as error indicators. * * Side Effects: * * */long append(name, fp, type, tftype, max, Outbuf) char *name; /* filename */ FILE *fp; int type, tftype, max; char *Outbuf; /* File writing buffer */{/* * +--> Local Variables */int done; /* Boolean used for segmented records */int fillbuf; /* Integer of amount of data to read to fill * line buffer to Blocksize */char *index(); /* subroutine to find first char in string */int length; /* Length of line */char line[MAXBLKWRT+1]; /* Line read in from file to output */int midway; /* Boolean used for segmented records */int notfini; /* Boolean used for TEXT loop */char *p; /* Pointer to the line input buffer */char *q; /* Pointer to the line input buffer */int used = 0; /* Number of characters used in Buffer for * segmented records *//*------*\ Code\*------*/Blocks = 0L;p = Outbuf;/*------*\ TEXT FILE\*------*/if (type == TEXT) { notfini = TRUE; midway = FALSE; q = line; fillbuf = Blocksize; while (notfini != EOF) { if (tftype != SYMLNK || Nosym) { if ((i = read(fileno(fp), q, fillbuf)) <= 0) if (i < 0) { PERROR "\n%s: %s %s\n", Progname, CANTRD, name); perror(Progname); exit(FAIL); } else break; q[i] = '\0'; } else strcpy(line, Outbuf); q = line; done = FALSE; while (done == FALSE) { if (cp = index(q, '\n')) *cp = '\0'; else if (Format == VARIABLE) break; length = strlen(q); if (length > max) return((long)(-1)); if (Format == VARIABLE) { if (&p[length+4] > &Outbuf[Blocksize]) { while (p < &Outbuf[Blocksize]) *p++ = PAD; if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) { PERROR "\n%s: %s %s\n", Progname, ERRWRF, name); perror(Magtdev); ceot(); } p = Outbuf; Blocks++; } sprintf(p, "%04d%s", length+4, q); p = &p[length+4]; q = ++cp; }/*T if (Format == VARIABLE) */ else { if (&p[length+5] <= &Outbuf[Blocksize]) { if (cp) { if (midway == FALSE) sprintf(p, "%01d%04d%s", 0, length+5, q); else { sprintf(p, "%01d%04d%s", 3, length+5, q); midway = FALSE; }/*F if (midway == FALSE) */ used += length + 5; p = &p[length+5]; q = ++cp; }/*T if (cp) */ else { strcpy(line, q); q = &line[length]; fillbuf = Blocksize - length; done = TRUE; }/*F if (cp) */ }/* T if (&p[length+5] <= ... */ else { if (used + 5 < Blocksize) { if (midway == FALSE) { sprintf(p, "%01d%04d%s", 1, Blocksize-used, q); midway = TRUE; }/*T if (midway == FALSE) */ else sprintf(p, "%01d%04d%s", 2, Blocksize-used, q); q = &q[Blocksize-used-5]; length -= Blocksize-used-5; }/* T if (used + 5 < Blocksize) */ else while (p < &Outbuf[Blocksize]) *p++ = PAD; used = 0; if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) { PERROR "\n%s: %s %s\n", Progname, ERRWRF, name); perror(Magtdev); ceot(); } p = Outbuf; Blocks++; if (cp) q[length] = '\n'; if (strlen(q) == 0) { q = line; fillbuf = Blocksize; done = TRUE; } }/*F if (&p[length+5] <= ... */ }/*F if (Format == VARIABLE) */ }/*E while (done == FALSE) */ if (tftype == SYMLNK && !Nosym) notfini = EOF; if (Format == VARIABLE) { length = strlen(q); strcpy(line, q); q = &line[length]; fillbuf = Blocksize - length; } }/*E while (notfini != EOF */ if (p != Outbuf) { while (p < &Outbuf[Blocksize]) *p++ = PAD; if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) { PERROR "\n%s: %s %s\n", Progname, ERRWRF, name); perror(Magtdev); ceot(); } Blocks++; }}/*T if type == TEXT *//*------*\ BINARY FILE\*------*/if (type == BINARY) { while ((length = read(fileno(fp), p=Outbuf, Blocksize)) > 0) { if (length < Blocksize) { p = &p[length]; while (p < &Outbuf[Blocksize]) *p++ = PAD; } if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) { PERROR "\n%s: %s %s\n", Progname, ERRWRF, name); perror(Magtdev); ceot(); } p = Outbuf; Blocks++; }/*E while length = read ..*/ if (length < 0) { PERROR "\n%s: %s %s\n", Progname, CANTRD, name); perror(Progname); exit(FAIL); }}/*T if (type == BINARY) *//*------*\ COUNTED RECORD FILE \*------*/if (type == COUNTED) { while ( fread((char *)&length, sizeof (short), 1, fp)) { if ( length == -1 || p+length+4 > &Outbuf[Blocksize]) { while ( p < &Outbuf[Blocksize]) *p++ = PAD; if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) { PERROR "\n%s: %s %s\n", Progname, ERRWRF, name); perror(Magtdev); ceot(); } p = Outbuf; Blocks++; }/*E if length == -1 ..*/ sprintf( p, "%04d", length+4); if (!fread( p+4, 2, (length+1)/2, fp)) { PERROR "\n%s: %s %s\n", Progname, CANTRD, name); perror(Magtdev); exit(FAIL); } /* * Fudge for COUNTED records always beginning * on a word boundary in file */ p += length+4; }/*E while fread ..*/ if (p != Outbuf) { while (p < &Outbuf[Blocksize]) *p++ = PAD; if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) { PERROR "\n%s: %s %s\n", Progname, ERRWRF, name); perror(Magtdev); ceot(); } Blocks++; }/*E if p != Outbuf */}/*T if type == counted *//*------*\ FORTRAN UNFORMATTED FILE\*------*/if (type == FUF) { /* * +--> Local Variables */ long bytcnt; int irec; int lastbit; int nrec; long nbytes, nbytesl; char rectype; int res, resl; char *rp; /* * Initialize buffer pointers */ Bb = Outbuf; Rb = Bb; rp = Rb + RECOFF; /* * Loop over all records in the file. The unformatted * format for f77 is as follows: each record is * followed and preceded by a long int which contains * the byte count of the record excluding the 2 long * integers. */ while ((res = read(fileno(fp), (char *)&nbytes, sizeof(long))) > 0) { if (nbytes > 0L) { bytcnt = nbytes; nrec = ((int)nbytes-1) / MAXREC6; irec = nrec; /* * if record is greater than MAXREC6, * then output it in chunks of MAXREC6 * first. */ while (irec--) { if (Rb - Bb + MAXRECFUF > Blocksize) { bflush(name, Outbuf); Rb = Bb; rp = Rb + RECOFF; } /* * Read record in chunks of MAXREC6 */ res = read(fileno(fp), rp, MAXREC6); if (res < 0) { PERROR "\n%s: %s%c\n\n", Progname, EOFINM, BELL); return((long)(-1)); } if (res != MAXREC6) { PERROR "%\n%s: %s%c\n\n", Progname, WRLINM, BELL); return((long)(-1)); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?