📄 buffer.c
字号:
corrupt |= ar_read(); } if (chunk > len) { chunk = len; } bufidx += chunk; len -= chunk; total += chunk; } return (corrupt);}/* buf_read - read a given number of characters from the input archive * * DESCRIPTION * * Reads len number of characters from the input archive and * stores them in the buffer pointed at by dst. * * PARAMETERS * * char *dst - pointer to buffer to store data into * uint len - length of data to read * * RETURNS * * Returns zero with valid data, -1 if unreadable portions were * replaced by null characters. */#ifdef __STDC__int buf_read(char *dst, uint len)#elseint buf_read(dst, len)char *dst;uint len;#endif{ int have; int want; int corrupt = 0; char *endx = dst + len; while (want = endx - dst) { if (bufend - bufidx < 0) { fatal("Buffer overlow in buf_read\n"); } while ((have = bufend - bufidx) == 0) { have = 0; corrupt |= ar_read(); } if (have > want) { have = want; } memcpy(dst, bufidx, have); bufidx += have; dst += have; total += have; } return (corrupt);}/* indata - install data from an archive * * DESCRIPTION * * Indata writes size bytes of data from the archive buffer to the output * file specified by fd. The filename which is being written, pointed * to by name is provided only for diagnostics. * * PARAMETERS * * int fd - output file descriptor * OFFSET size - number of bytes to write to output file * char *name - name of file which corresponds to fd * * RETURNS * * Returns given file descriptor. */#ifdef __STDC__static int indata(int fd, OFFSET size, char *name)#elsestatic int indata(fd, size, name)int fd;OFFSET size;char *name;#endif{ uint chunk; char *oops; int sparse; int corrupt; char *buf; uint avail; corrupt = sparse = 0; oops = (char *)NULL; while (size) { corrupt |= buf_in_avail(&buf, &avail); size -= (chunk = size < avail ? (uint) size : avail); if (oops == (char *)NULL && (sparse = ar_write(fd, buf, chunk)) < 0) { oops = strerror(); } buf_use(chunk); } if (corrupt) { warn(name, "Corrupt archive data"); } if (oops) { warn(name, oops); } else if (sparse > 0 && (lseek(fd, (OFFSET) - 1, 1) < 0 || write(fd, "", 1) != 1)) { warn(name, strerror()); } return (fd);}/* outflush - flush the output buffer * * DESCRIPTION * * The output buffer is written, if there is anything in it, to the * archive file. */#ifdef __STDC__static void outflush(void)#elsestatic void outflush()#endif{ char *buf; int got; uint len; /* if (bufidx - buf > 0) */ for (buf = bufstart; len = bufidx - buf;) { if ((got = write(archivefd, buf, MIN(len, blocksize))) > 0) { buf += got; } else if (got < 0) { next(AR_WRITE); } } bufend = (bufidx = bufstart) + blocksize;}/* ar_read - fill the archive buffer * * DESCRIPTION * * Remembers mid-buffer read failures and reports them the next time * through. Replaces unreadable data with null characters. Resets * the buffer pointers as appropriate. * * RETURNS * * Returns zero with valid data, -1 otherwise. */#ifdef __STDC__int ar_read(void)#elseint ar_read()#endif{ int got; static int failed; bufend = bufidx = bufstart; if (!failed) { if (areof) { if (total == 0) { fatal("No input"); } else { next(AR_READ); } } while (!failed && !areof && bufstart + blocksize - bufend >= blocksize) { if ((got = read(archivefd, bufend, (unsigned int) blocksize)) > 0) { bufend += got; } else if (got < 0) { failed = -1; warnarch(strerror(), (OFFSET) 0 - (bufend - bufidx)); } else { ++areof; } } } if (failed && bufend == bufstart) { failed = 0; for (got = 0; got < blocksize; ++got) { *bufend++ = '\0'; } return (-1); } return (0);}/* ar_write - write a filesystem block * * DESCRIPTION * * Writes len bytes of data data from the specified buffer to the * specified file. Seeks past sparse blocks. * * PARAMETERS * * int fd - file to write to * char *buf - buffer to get data from * uint len - number of bytes to transfer * * RETURNS * * Returns 0 if the block was written, the given length for a sparse * block or -1 if unsuccessful. */#ifdef __STDC__static int ar_write(int fd, char *buf, uint len)#elsestatic int ar_write(fd, buf, len)int fd;char *buf;uint len;#endif{ char *bidx; char *bend; bend = (bidx = buf) + len; while (bidx < bend) { if (*bidx++) { return (write(fd, buf, len) == len ? 0 : -1); } } return (lseek(fd, (OFFSET) len, 1) < 0 ? -1 : len);}/* buf_pad - pad the archive buffer * * DESCRIPTION * * Buf_pad writes len zero bytes to the archive buffer in order to * pad it. * * PARAMETERS * * OFFSET pad - number of zero bytes to pad * */#ifdef __STDC__static void buf_pad(OFFSET pad)#elsestatic void buf_pad(pad)OFFSET pad;#endif{ int idx; int have; while (pad) { if ((have = bufend - bufidx) > pad) { have = pad; } for (idx = 0; idx < have; ++idx) { *bufidx++ = '\0'; } total += have; pad -= have; if (bufend - bufidx == 0) { outflush(); } }}/* buf_use - allocate buffer space * * DESCRIPTION * * Buf_use marks space in the buffer as being used; advancing both the * buffer index (bufidx) and the total byte count (total). * * PARAMETERS * * uint len - Amount of space to allocate in the buffer */#ifdef __STDC__static void buf_use(uint len)#elsestatic void buf_use(len)uint len;#endif{ bufidx += len; total += len;}/* buf_in_avail - index available input data within the buffer * * DESCRIPTION * * Buf_in_avail fills the archive buffer, and points the bufp * parameter at the start of the data. The lenp parameter is * modified to contain the number of bytes which were read. * * PARAMETERS * * char **bufp - pointer to the buffer to read data into * uint *lenp - pointer to the number of bytes which were read * (returned to the caller) * * RETURNS * * Stores a pointer to the data and its length in given locations. * Returns zero with valid data, -1 if unreadable portions were * replaced with nulls. * * ERRORS * * If an error occurs in ar_read, the error code is returned to the * calling function. * */#ifdef __STDC__static int buf_in_avail(char **bufp, uint *lenp)#elsestatic int buf_in_avail(bufp, lenp)char **bufp;uint *lenp;#endif{ uint have; int corrupt = 0; while ((have = bufend - bufidx) == 0) { corrupt |= ar_read(); } *bufp = bufidx; *lenp = have; return (corrupt);}/* buf_out_avail - index buffer space for archive output * * DESCRIPTION * * Stores a buffer pointer at a given location. Returns the number * of bytes available. * * PARAMETERS * * char **bufp - pointer to the buffer which is to be stored * * RETURNS * * The number of bytes which are available in the buffer. * */#ifdef __STDC__static uint buf_out_avail(char **bufp)#elsestatic uint buf_out_avail(bufp)char **bufp;#endif{ int have; if (bufend - bufidx < 0) { fatal("Buffer overlow in buf_out_avail\n"); } if ((have = bufend - bufidx) == 0) { outflush(); } *bufp = bufidx; return (have);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -