⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tar.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* Should there be a timestamp if the chown failes? -- KS */  timestamp(file);}void timestamp(file)char *file;{  struct utimbuf buf;  buf.modtime = buf.actime = convert(header.dbuf.mtime, LONG_TYPE);  utime(file, &buf);}void copy(file, from, to, bytes)char *file;int from, to;register long bytes;{  register int rest;  int blocks = (int) ((bytes + (long) TBLOCK_SIZE - 1) / (long) TBLOCK_SIZE);  if (verbose_flag)	string_print(NIL_PTR, "%s, %d tape blocks\n", file, blocks);  while (blocks--) {	(void) bread(from, io_buffer, TBLOCK_SIZE);	rest = (bytes > (long) TBLOCK_SIZE) ? TBLOCK_SIZE : (int) bytes;	mwrite(to, io_buffer, (to == tar_fd) ? TBLOCK_SIZE : rest);	bytes -= (long) rest;  }}long convert(str, type)char str[];int type;{  register long ac = 0L;  register int i;  for (i = 0; i < type; i++) {	if (str[i] >= '0' && str[i] <= '7') {		ac <<= 3;		ac += (long) (str[i] - '0');	}  }  return ac;}int checksum(){  register char *ptr = header.member.m_checksum;  register int ac = 0;  while (ptr < &header.member.m_checksum[INT_TYPE]) *ptr++ = ' ';  ptr = header.hdr_block;  while (ptr < &header.hdr_block[TBLOCK_SIZE]) ac += *ptr++;  return ac;}int is_dir(file)register char *file;{  while (*file++ != '\0');  return(*(file - 2) == '/');}char *path_name(file)register char *file;{  string_print(pathname, "%s%s", path, file);  return pathname;}void add_path(name)register char *name;{  register char *path_ptr = path;  while (*path_ptr) path_ptr++;  if (name == NIL_PTR) {	while (*path_ptr-- != '/');	while (*path_ptr != '/' && path_ptr != path) path_ptr--;	if (*path_ptr == '/') path_ptr++;	*path_ptr = '\0';  } else {	while (*name) {		if (path_ptr == &path[NAME_SIZE])			error("Pathname too long", NIL_PTR);		*path_ptr++ = *name++;	}	*path_ptr++ = '/';	*path_ptr = '\0';  }}/* *	add a file to the archive*/void add_file(file)register char *file;{  struct stat st;  char *linkname;  register int fd = -1;  char namebuf[16];		/* -Dal */  char cwd[129];		/* -KS */#ifdef HAVE_SYMLINK  if (lstat(file, &st) < 0) {#else  if (stat(file, &st) < 0) {#endif	string_print(NIL_PTR, "%s: %s\n", file, strerror(errno));	return;  }  if (st.st_dev == ar_dev && st.st_ino == ar_inode) {	string_print(NIL_PTR, "Cannot tar current archive file (%s)\n", file);	return;  }				/* marks@mgse Mon Sep 25 12:06:28 CDT 1989 */  if ((fd = add_open(file, &st)) < 0) {	string_print(NIL_PTR, "Cannot open %s\n", file);	return;  }  make_header(path_name(file), &st);  if ((linkname = is_linked(&st)) != NULL) {	strncpy(header.dbuf.linkname, linkname, (size_t) NAMSIZ);	header.dbuf.typeflag = '1';	if (verbose_flag) string_print(NIL_PTR, "linked %s to %s\n",			     header.dbuf.linkname, file);	string_print(header.member.m_checksum, "%I ", checksum());	mwrite(tar_fd, (char *) &header, sizeof(header));  } else {	is_added(&st, file);	switch (st.st_mode & S_IFMT) {	    case S_IFREG:		header.dbuf.typeflag = '0';		string_print(header.member.m_checksum, "%I ", checksum());		mwrite(tar_fd, (char *) &header, sizeof(header));		copy(path_name(file), fd, tar_fd, (long) st.st_size);		break;	    case S_IFDIR:		header.dbuf.typeflag = '5';		string_print(header.member.m_checksum, "%I ", checksum());		mwrite(tar_fd, (char *) &header, sizeof(header));		verb_print("read directory", file);		if (norec_flag) break;		if (NULL == getcwd(cwd, (int) sizeof cwd))			string_print(NIL_PTR, "Error: cannot getcwd()\n");		else if (chdir(file) < 0)			string_print(NIL_PTR, "Cannot chdir to %s: %s\n",				file, strerror(errno));		else {			add_path(file);#ifdef	DIRECT_3			{				DIR *dirp;				struct direct *dp;				struct stat dst;				add_close(fd);				fd= 0;				dirp = opendir(".");				while (NULL != (dp = readdir(dirp)))					if (strcmp(dp->d_name, ".") == 0)						is_linked(&st);					else if (strcmp(dp->d_name, "..") == 0) {						if (stat("..", &dst) == 0)							is_linked(&dst);					} else {						strcpy(namebuf, dp->d_name);						add_file(namebuf);					}				closedir(dirp);			}#else			{				int i;				struct direct dir;				struct stat dst;				for (i = 0; i < 2; i++) {	/* . and .. */					mread(fd, &dir, sizeof(dir));					if (strcmp(dir.d_name, ".") == 0)						is_linked(&st);					else if (strcmp(dir.d_name, "..") == 0) {						if (stat("..", &dst) == 0)							is_linked(&dst);					} else						break;				}				while (bread(fd, &dir, sizeof(dir)) == sizeof(dir))					if (dir.d_ino) {						strncpy(namebuf, dir.d_name,						   (size_t) DIRSIZ);						namebuf[DIRSIZ] = '\0';						add_file(namebuf);					}			}#endif			chdir(cwd);			add_path(NIL_PTR);			*file = 0;		}		break;#ifdef HAVE_SYMLINK	    case S_IFLNK:		{			int i;			header.dbuf.typeflag = '2';			verb_print("read symlink", file);			i = readlink(file,				     header.dbuf.linkname,				  sizeof(header.dbuf.linkname) - 1);			if (i < 0) {				string_print(NIL_PTR,					"Cannot read symbolic link %s: %s\n",					file, strerror(errno));				return;			}			header.dbuf.linkname[i] = 0;			string_print(header.member.m_checksum, "%I ", checksum());			mwrite(tar_fd, (char *) &header, sizeof(header));			break;		}#endif#ifdef HAVE_FIFO	    case S_IFIFO:		header.dbuf.typeflag = '6';		verb_print("read fifo", file);		string_print(header.member.m_checksum, "%I ", checksum());		mwrite(tar_fd, (char *) &header, sizeof(header));		break;#endif	    case S_IFBLK:		header.dbuf.typeflag = '4';		if (verbose_flag) {			char sizebuf[TSIZLEN + 1];			strncpy(sizebuf, header.dbuf.size, (size_t) TSIZLEN);			sizebuf[TSIZLEN] = 0;			string_print(NIL_PTR,			 "read block device %s major %s minor %s\n",				     file, header.dbuf.devmajor, header.dbuf.devminor, sizebuf);		}		string_print(header.member.m_checksum, "%I ", checksum());		mwrite(tar_fd, (char *) &header, sizeof(header));		break;	    case S_IFCHR:		header.dbuf.typeflag = '3';		if (verbose_flag) string_print(NIL_PTR,				     "read character device %s major %s minor %s\n",				     file, header.dbuf.devmajor, header.dbuf.devminor);		string_print(header.member.m_checksum, "%I ", checksum());		mwrite(tar_fd, (char *) &header, sizeof(header));		break;	    default:		is_deleted(&st);		string_print(NIL_PTR, "Tar: %s unknown file type. Not added.\n", file);		*file = 0;	}  }  flush();  add_close(fd);}void verb_print(s1, s2)char *s1, *s2;{  if (verbose_flag) string_print(NIL_PTR, "%s: %s\n", s1, s2);}void add_close(fd)int fd;{  if (fd != 0) close(fd);}/* *	open file 'file' to be added to archive, return file descriptor*/int add_open(file, st)char *file;struct stat *st;{  int fd;  if (((st->st_mode & S_IFMT) != S_IFREG) &&      ((st->st_mode & S_IFMT) != S_IFDIR))	return 0;  fd = open(file, O_RDONLY);  if (fd == -1)  	fprintf(stderr, "open failed: %s\n", strerror(errno));  return fd;}void make_header(file, st)char *file;register struct stat *st;{  register char *ptr = header.member.m_name;  struct passwd *pwd;  struct group *grp;  clear_header();  while (*ptr++ = *file++);  if ((st->st_mode & S_IFMT) == S_IFDIR) {	/* fixed test  -Dal */	*(ptr - 1) = '/';  }  string_print(header.member.m_mode, "%I ", st->st_mode & 07777);  string_print(header.member.m_uid, "%I ", st->st_uid);  string_print(header.member.m_gid, "%I ", st->st_gid);  if ((st->st_mode & S_IFMT) == S_IFREG)	string_print(header.member.m_size, "%L ", st->st_size);  else	strncpy(header.dbuf.size, "0", (size_t) TSIZLEN);  string_print(header.member.m_time, "%L ", st->st_mtime);  strncpy(header.dbuf.magic, TMAGIC, (size_t) TMAGLEN);  header.dbuf.version[0] = 0;  header.dbuf.version[1] = 0;  pwd = getpwuid(st->st_uid);  strncpy(header.dbuf.uname,	(pwd != NULL ? pwd->pw_name : "nobody"), TUNMLEN);  grp = getgrgid(st->st_gid);  strncpy(header.dbuf.gname,	(grp != NULL ? grp->gr_name : "nobody"), TGNMLEN);  if (st->st_mode & (S_IFBLK | S_IFCHR)) {	string_print(header.dbuf.devmajor, "%I ", (st->st_rdev >> 8));	string_print(header.dbuf.devminor, "%I ", (st->st_rdev & 0xFF));  }  header.dbuf.prefix[0] = 0;}void is_added(st, file)struct stat *st;char *file;{  struct link *new;  char *name;  if ((*file == 0) || (st->st_nlink == 1)) return;  name = path_name(file);  new = (struct link *) malloc(sizeof(struct link) + strlen(name));  if (new == NULL) {	print("Out of memory\n");	return;  }  new->next = link_top;  new->dev = st->st_dev;  new->ino = st->st_ino;  new->nlink = st->st_nlink - 1;  strcpy(new->name, name);  link_top = new;}void is_deleted(st)struct stat *st;{  struct link *old;  if ((old = link_top) != NULL) {	link_top = old->next;	free(old);  }}char *is_linked(st)struct stat *st;{  struct link *cur = link_top;  struct link **pre = &link_top;  static char name[NAMSIZ];  while (cur != NULL)	if ((cur->dev != st->st_dev) || (cur->ino != st->st_ino)) {		pre = &cur->next;		cur = cur->next;	} else {		if (--cur->nlink == 0) {			*pre = cur->next;			strncpy(name, cur->name, NAMSIZ);			return name;		}		return cur->name;	}  return NULL;}void clear_header(){  register char *ptr = header.hdr_block;  while (ptr < &header.hdr_block[TBLOCK_SIZE]) *ptr++ = '\0';}void adjust_boundary(){  clear_header();  mwrite(tar_fd, (char *) &header, sizeof(header));#ifndef POSIX_COMP  while (total_blocks++ < BLOCK_BOUNDARY)	mwrite(tar_fd, (char *) &header, sizeof(header));#else  mwrite(tar_fd, (char *) &header, sizeof(header));#endif  (void) close(tar_fd);}void mread(fd, address, bytes)int fd, bytes;char *address;{  if (bread(fd, address, bytes) != bytes) error("Tar: read error.", NIL_PTR);}void mwrite(fd, address, bytes)int fd, bytes;char *address;{  if (bwrite(fd, address, bytes) != bytes) error("Tar: write error.", NIL_PTR);  total_blocks++;}int bread(fd, address, bytes)int fd, bytes;char *address;{  int n = 0, r;  while (n < bytes) {	if ((r = read(fd, address + n, bytes - n)) <= 0) {		if (r < 0) return r;		break;	}	n += r;  }  return n;}int bwrite(fd, address, bytes)int fd, bytes;char *address;{  int n = 0, r;  while (n < bytes) {	if ((r = write(fd, address + n, bytes - n)) <= 0) {		if (r < 0) return r;		break;	}	n += r;  }  return n;}char output[TBLOCK_SIZE];void print(str)			/* changed to use stderr rather than stdout			 * -Dal */register char *str;{  static int indx = 0;  if (str == NIL_PTR) {	write(2, output, indx);	indx = 0;	return;  }  while (*str) {	output[indx++] = *str++;	if (indx == TBLOCK_SIZE) {		write(2, output, TBLOCK_SIZE);		indx = 0;	}  }}char *num_out(number)register long number;{  static char num_buf[12];  register int i;  for (i = 11; i--;) {	num_buf[i] = (number & 07) + '0';	number >>= 3;  }  return num_buf;}/*VARARGS2*/#if __STDC__void string_print(char *buffer, char *fmt,...)#elsevoid string_print(buffer, fmt)char *buffer;char *fmt;#endif{  va_list args;  register char *buf_ptr;  char *scan_ptr;  char buf[STRING_SIZE];  BOOL pr_fl, i;  if (pr_fl = (buffer == NIL_PTR)) buffer = buf;  va_start(args, fmt);  buf_ptr = buffer;  while (*fmt) {	if (*fmt == '%') {		fmt++;		switch (*fmt++) {		    case 's':			scan_ptr = (char *) (va_arg(args, char *));			break;		    case 'I':			scan_ptr = num_out((long) (va_arg(args, int)));			for (i = 0; i < 5; i++) scan_ptr++;			break;		    case 'L':			scan_ptr = num_out((long) va_arg(args, long));			break;		    case 'd':			scan_ptr = num_out((long) va_arg(args, int));			while (*scan_ptr == '0') scan_ptr++;			scan_ptr--;			break;		    default:	scan_ptr = "";		}		while (*buf_ptr++ = *scan_ptr++);		buf_ptr--;	} else		*buf_ptr++ = *fmt++;  }  *buf_ptr = '\0';  if (pr_fl) print(buffer);  va_end(args);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -