📄 shift.c
字号:
/* shift.c -- utilities to move regions of data in a file. Copyright (C) 2004 Free Software Foundation, Inc.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or (atyour option) any later version. This program is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details. You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA. */#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include "jartool.h"#include "shift.h"#define BUFFER_SIZE 1024#define MIN(a, b) ((a) < (b) ? (a) : (b))/* * Shift the contents of a file up by `amount' bytes, starting at `begin'. * The file is not truncated, data from `amount' to `begin - amount' is * overwritten. The current file pointer of `fd' is preserved. Note that * this might be past the new "end" of the file. * * If this function is passed a `struct zipentry', then all `offset' * fields from that entry down the list that are greater than or equal * to `begin' will be decreased by `amount'. * * fd - The file descriptor. * begin - The offset of the first byte that should be shifted. * amount - The number of bytes to shift by. * ze - A pointer into a list of zip entries that should be updated * to reflect the modified offset. */intshift_up (int fd, off_t begin, off_t amount, struct zipentry *ze){ extern off_t end_of_entries; int len, moved = 0; ub1 buffer[BUFFER_SIZE]; off_t where, end, save; if (amount <= 0) return 0; if ((save = lseek (fd, 0, SEEK_CUR)) == -1) return 1; if ((end = lseek (fd, 0, SEEK_END)) == -1) return 1; if (end < begin) return 0; where = begin; do { if (lseek (fd, where, SEEK_SET) < 0) return 1; if ((len = read (fd, buffer, BUFFER_SIZE)) < 0) return 1; if (len == 0) break; if (lseek (fd, where - amount, SEEK_SET) < 0) return 1; if (write (fd, buffer, len) < 0) return 1; where += len; } while (where < end); for (; ze; ze = ze->next_entry) { if (ze->offset >= begin) { ze->offset -= amount; moved = 1; } } if (moved) end_of_entries -= amount; if (lseek (fd, save, SEEK_SET) == -1) return 1; return 0;}/* * Shift the contents of this file down by `amount' bytes, extending the * end of file, starting at `begin'. This function will preserve the * current file pointer of `fd'. Naturally, this function will fail if * `fd' is not seekable. * * If this function is passed a `struct zipentry', then all `offset' * fields from that entry down the list that are greater than or equal * to `begin' will be increased by `amount'. * * fd - The file descriptor. * begin - The offset of the first byte that should be shifted. * amount - The number of bytes to shift by. * ze - A pointer into a list of zip entries that should be updated * to reflect the modified offset. */intshift_down (int fd, off_t begin, off_t amount, struct zipentry *ze){ extern off_t end_of_entries; int off, len, moved = 0; ub1 buffer[BUFFER_SIZE]; off_t where, save; if (amount <= 0) return 0; if ((save = lseek (fd, 0, SEEK_CUR)) == -1) return 1; if ((where = lseek (fd, 0, SEEK_END)) == -1) return 1; if (where < begin) return 0; off = (where - begin) % BUFFER_SIZE; if (off == 0) where -= BUFFER_SIZE; else where -= off; do { if (lseek (fd, where, SEEK_SET) < 0) return 1; if ((len = read (fd, buffer, BUFFER_SIZE)) < 0) return 1; if (lseek (fd, where + amount, SEEK_SET) < 0) return 1; if (write (fd, buffer, len) < 0) return 1; where -= BUFFER_SIZE; } while (where >= begin); for (; ze; ze = ze->next_entry) { if (ze->offset >= begin) { ze->offset += amount; moved = 1; } } if (moved) end_of_entries += amount; if (lseek (fd, save, SEEK_SET) == -1) return 1; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -