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

📄 port.c

📁 一个类似Unix下tar命令的tar程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	int		fd;
	
	errno = ENXIO;		/* No such device or address */
	return -1;		/* Just give an error */
}

/* Fake links by copying */
int
link(path1, path2)
	char		*path1;
	char		*path2;
{
	char	buf[256];
	int	ifd, ofd;
	int	nrbytes;
	int	nwbytes;

	fprintf(stderr, "%s: %s: cannot link to %s, copying instead\n",
		tar, path1, path2);
	if ((ifd = open(path1, O_RDONLY|O_BINARY)) < 0)
		return -1;
	if ((ofd = creat(path2, 0666)) < 0)
		return -1;
	setmode(ofd, O_BINARY);
	while ((nrbytes = read(ifd, buf, sizeof(buf))) > 0) {
		if ((nwbytes = write(ofd, buf, nrbytes)) != nrbytes) {
			nrbytes = -1;
			break;
		}
	}
	/* Note use of "|" rather than "||" below: we want to close
	 * the files even if an error occurs.
	 */
	if ((nrbytes < 0) | (0 != close(ifd)) | (0 != close(ofd))) {
		unlink(path2);
		return -1;
	}
	return 0;
}

/* everyone owns everything on MS-DOS (or is it no one owns anything?) */
int
chown(path, uid, gid)
	char	*path;
	int	uid;
	int	gid;
{
	return 0;
}

int
geteuid()
{
	return 0;
}
#endif	/* WANT_MKNOD */

#ifdef WANT_UTILS
/* Stash argv[0] here so panic will know what the program is called */
char *myname = 0;

void
panic(s)
char *s;
{
	if(myname)
		fprintf(stderr,"%s:",myname);
	fprintf(stderr,s);
	putc('\n',stderr);
	exit(12);
}


char *
ck_malloc(size)
size_t size;
{
	char *ret;
	char *malloc();

	if(!size)
		size++;
	ret=malloc(size);
	if(ret==0)
		panic("Couldn't allocate memory");
	return ret;
}

char *
ck_realloc(ptr,size)
char *ptr;
size_t size;
{
	char *ret;
	char *realloc();

	if(!ptr)
		ret=ck_malloc(size);
	else
		ret=realloc(ptr,size);
	if(ret==0)
		panic("Couldn't re-allocate memory");
	return ret;
}

/* Implement a variable sized buffer of 'stuff'.  We don't know what it is,
   nor do we care, as long as it doesn't mind being aligned on a char boundry.
 */

struct buffer {
	int	allocated;
	int	length;
	char	*b;
};

#define MIN_ALLOCATE 50

char *
init_buffer()
{
	struct buffer *b;

	b=(struct buffer *)ck_malloc(sizeof(struct buffer));
	b->allocated=MIN_ALLOCATE;
	b->b=(char *)ck_malloc(MIN_ALLOCATE);
	b->length=0;
	return (char *)b;
}

void
flush_buffer(bb)
char *bb;
{
	struct buffer *b;

	b=(struct buffer *)bb;
	free(b->b);
	b->b=0;
	b->allocated=0;
	b->length=0;
	free((void *)b);
}

void
add_buffer(bb,p,n)
char *bb;
char *p;
int n;
{
	struct buffer *b;

	b=(struct buffer *)bb;
	if(b->length+n>b->allocated) {
		b->allocated=b->length+n+MIN_ALLOCATE;
		b->b=(char *)ck_realloc(b->b,b->allocated);
	}
	bcopy(p,b->b+b->length,n);
	b->length+=n;
}

char *
get_buffer(bb)
char *bb;
{
	struct buffer *b;

	b=(struct buffer *)bb;
	return b->b;
}

char *
merge_sort(list,n,off,cmp)
char *list;
int (*cmp)();
unsigned n;
int off;
{
	char *ret;

	char *alist,*blist;
	unsigned alength,blength;

	char *tptr;
	int tmp;
	char **prev;
#define NEXTOF(ptr)	(* ((char **)(((char *)(ptr))+off) ) )
	if(n==1)
		return list;
	if(n==2) {
		if((*cmp)(list,NEXTOF(list))>0) {
			ret=NEXTOF(list);
			NEXTOF(ret)=list;
			NEXTOF(list)=0;
			return ret;
		}
		return list;
	}
	alist=list;
	alength=(n+1)/2;
	blength=n/2;
	for(tptr=list,tmp=(n-1)/2;tmp;tptr=NEXTOF(tptr),tmp--)
		;
	blist=NEXTOF(tptr);
	NEXTOF(tptr)=0;

	alist=merge_sort(alist,alength,off,cmp);
	blist=merge_sort(blist,blength,off,cmp);
	prev = &ret;
	for(;alist && blist;) {
		if((*cmp)(alist,blist)<0) {
			tptr=NEXTOF(alist);
			*prev = alist;
			prev = &(NEXTOF(alist));
			alist=tptr;
		} else {
			tptr=NEXTOF(blist);
			*prev = blist;
			prev = &(NEXTOF(blist));
			blist=tptr;
		}
	}
	if(alist)
		*prev = alist;
	else
		*prev = blist;

	return ret;
}

void
ck_close(fd)
int fd;
{
	if(close(fd)<0) {
		msg_perror("can't close a file #%d",fd);
		exit(EX_SYSTEM);
	}
}

#include <ctype.h>

/* Quote_copy_string is like quote_string, but instead of modifying the
   string in place, it malloc-s a copy  of the string, and returns that.
   If the string does not have to be quoted, it returns the NULL string.
   The allocated copy can, of course, be freed with free() after the
   caller is done with it.
 */
char *
quote_copy_string(string)
char *string;
{
	char	*from_here;
	char	*to_there = 0;
	char	*copy_buf = 0;
	int	c;
	int	copying = 0;

	from_here=string;
	while(*from_here) {
		c= *from_here++;
		if(c=='\\') {
			if(!copying) {
				int n;

				n=(from_here-string)-1;
				copying++;
				copy_buf=(char *)malloc(n+5+strlen(from_here)*4);
				if(!copy_buf)
					return 0;
				bcopy(string,copy_buf,n);
				to_there=copy_buf+n;
			}
			*to_there++='\\';
			*to_there++='\\';
		} else if(isprint(c)) {
			if(copying)
				*to_there++= c;
		} else {
			if(!copying) {
				int	n;

				n=(from_here-string)-1;
				copying++;
				copy_buf=(char *)malloc(n+5+strlen(from_here)*4);
				if(!copy_buf)
					return 0;
				bcopy(string,copy_buf,n);
				to_there=copy_buf+n;
			}
			*to_there++='\\';
			if(c=='\n') *to_there++='n';
			else if(c=='\t') *to_there++='t';
			else if(c=='\f') *to_there++='f';
			else if(c=='\b') *to_there++='b';
			else if(c=='\r') *to_there++='r';
			else if(c=='\177') *to_there++='?';
			else {
				to_there[0]=(c>>6)+'0';
				to_there[1]=((c>>3)&07)+'0';
				to_there[2]=(c&07)+'0';
				to_there+=3;
			}
		}
	}
	if(copying) {
		*to_there='\0';
		return copy_buf;
	}
	return (char *)0;
}


/* Un_quote_string takes a quoted c-string (like those produced by
   quote_string or quote_copy_string and turns it back into the
   un-quoted original.  This is done in place.
 */

/* There is no un-quote-copy-string.  Write it yourself */

char *un_quote_string(string)
char *string;
{
	char *ret;
	char *from_here;
	char *to_there;
	int	tmp;

	ret=string;
	to_there=string;
	from_here=string;
	while(*from_here) {
		if(*from_here!='\\') {
			if(from_here!=to_there)
				*to_there++= *from_here++;
			else
				from_here++,to_there++;
			continue;
		}
		switch(*++from_here) {
		case '\\':
			*to_there++= *from_here++;
			break;
		case 'n':
			*to_there++= '\n';
			from_here++;
			break;
		case 't':
			*to_there++= '\t';
			from_here++;
			break;
		case 'f':
			*to_there++= '\f';
			from_here++;
			break;
		case 'b':
			*to_there++= '\b';
			from_here++;
			break;
		case 'r':
			*to_there++= '\r';
			from_here++;
			break;
		case '?':
			*to_there++= 0177;
			from_here++;
			break;
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
			tmp= *from_here - '0';
			from_here++;
			if(*from_here<'0' || *from_here>'7') {
				*to_there++= tmp;
				break;
			}
			tmp= tmp*8 + *from_here-'0';
			from_here++;
			if(*from_here<'0' || *from_here>'7') {
				*to_there++= tmp;
				break;
			}
			tmp=tmp*8 + *from_here-'0';
			from_here++;
			*to_there=tmp;
			break;
		default:
			ret=0;
			*to_there++='\\';
			*to_there++= *from_here++;
			break;
		}
	}
	if(*to_there)
		*to_there++='\0';
	return ret;
}
#endif

#ifdef WANT_CK_PIPE
void ck_pipe(pipes)
int *pipes;
{
	if(pipe(pipes)<0) {
		msg_perror("can't open a pipe");
		exit(EX_SYSTEM);
	}
}

#endif

#ifdef WANT_GETWD
char *
getwd(path)
char *path;
{
	FILE *fp;
	FILE *popen();

	fp=popen("pwd","r");
	if(!fp)
		return 0;
	if(!fgets(path,100,fp))
		return 0;
	if(!pclose(fp))
		return 0;
	return path;
}
#endif /* WANT_CK_PIPE */


#ifdef WANT_STRSTR

/*
 * strstr - find first occurrence of wanted in s
 */

char *				/* found string, or NULL if none */
strstr(s, wanted)
char *s;
char *wanted;
{
	register char *scan;
	register size_t len;
	register char firstc;
	extern int strcmp();

	if (*wanted == '\0')
	  return (char *)0;
	/*
	 * The odd placement of the two tests is so "" is findable.
	 * Also, we inline the first char for speed.
	 * The ++ on scan has been moved down for optimization.
	 */
	firstc = *wanted;
	len = strlen(wanted);
	for (scan = s; *scan != firstc || strncmp(scan, wanted, len) != 0; )
		if (*scan++ == '\0')
			return (char *)0;
	return scan;
}
#endif

#ifdef WANT_FTRUNCATE

#ifdef F_FREESP
/* code courtesy of William Kucharski */

int
ftruncate(fd, length)
int fd;                       /* file descriptor */
off_t length;         /* length to set file to */
{
	struct flock fl;

	fl.l_whence = 0;
	fl.l_len = 0;
	fl.l_start = length;
	fl.l_type = F_WRLCK;    /* write lock on file space */

	/*
	 * This relies on the UNDOCUMENTED F_FREESP argument to
	 * fcntl(2), which truncates the file so that it ends at the
	 * position indicated by fl.l_start.
	 *
	 * Will minor miracles never cease?
	 */

	if (fcntl(fd, F_FREESP, &fl) < 0)
	    return -1;

	return 0;
}


#else
int
ftruncate(fd, length)
int fd;
off_t length;
{
	errno = EIO;
	return -1;
}
#endif

#endif




extern FILE *msg_file;

#ifdef STDC_MSG
#include <stdarg.h>

void
msg(char *str,...)
{
	va_list args;

	va_start(args,str);
	fflush(msg_file);
	fprintf(stderr,"%s: ",tar);
	if(f_sayblock)
		fprintf(stderr,"rec %d: ",baserec + (ar_record - ar_block));
	vfprintf(stderr,str,args);
	va_end(args);
	putc('\n',stderr);
	fflush(stderr);
}

void
msg_perror(char *str,...)
{
	va_list args;
	int save_e;
	extern int errno;

	save_e=errno;
	fflush(msg_file);
	fprintf(stderr,"%s: ",tar);
	if(f_sayblock)
		fprintf(stderr,"rec %d: ",baserec + (ar_record - ar_block));
	va_start(args,str);
	vfprintf(stderr,str,args);
	va_end(args);
	errno=save_e;
	perror(" ");
	fflush(stderr);
}
#endif

#ifdef VARARGS_MSG
#include <varargs.h>
void msg(str,va_alist)
char *str;
va_dcl
{
	va_list args;

	fflush(msg_file);
	fprintf(stderr,"%s: ",tar);
	if(f_sayblock)
		fprintf(stderr,"rec %d: ",baserec + (ar_record - ar_block));
	va_start(args);
	vfprintf(stderr,str,args);
	va_end(args);
	putc('\n',stderr);
	fflush(stderr);
}

void msg_perror(str,va_alist)
char *str;
va_dcl
{
	va_list args;
	int save_e;
	extern int errno;

	save_e=errno;
	fflush(msg_file);
	fprintf(stderr,"%s: ",tar);
	if(f_sayblock)
		fprintf(stderr,"rec %d: ",baserec + (ar_record - ar_block));
	va_start(args);
	vfprintf(stderr,str,args);
	va_end(args);
	errno=save_e;
	perror(" ");
	fflush(stderr);
}
#endif

#ifdef DOPRNT_MSG
void msg(str,args)
char *str;
int args;
{
	fflush(msg_file);
	fprintf(stderr,"%s: ",tar);
	if(f_sayblock)
		fprintf(stderr,"rec %d: ",baserec + (ar_record - ar_block));
	_doprnt(str, &args, stderr);
	putc('\n',stderr);
	fflush(stderr);
}

void msg_perror(str,args)
char *str;
{
	int save_e;
	extern int errno;

	save_e=errno;
	fflush(msg_file);
	fprintf(stderr,"%s: ",tar);
	if(f_sayblock)
		fprintf(stderr,"rec %d: ",baserec + (ar_record - ar_block));
	_doprnt(str, &args, stderr);
	errno=save_e;
	perror(" ");
	fflush(stderr);
}

#endif
#ifdef LOSING_MSG
void msg(str,a1,a2,a3,a4,a5,a6)
char *str;
{
	fflush(msg_file);
	fprintf(stderr,"%s: ",tar);
	if(f_sayblock)
		fprintf(stderr,"rec %d: ",baserec + (ar_record - ar_block));
	fprintf(stderr,str,a1,a2,a3,a4,a5,a6);
	putc('\n',stderr);
	fflush(stderr);
}

void msg_perror(str,a1,a2,a3,a4,a5,a6)
char *str;
{
	int save_e;
	extern int errno;

	save_e=errno;
	fflush(msg_file);
	fprintf(stderr,"%s: ",tar);
	if(f_sayblock)
		fprintf(stderr,"rec %d: ",baserec + (ar_record - ar_block));
	fprintf(stderr,str,a1,a2,a3,a4,a5,a6);
	fprintf(stderr,": ");
	errno=save_e;
	perror(" ");
}

#endif

⌨️ 快捷键说明

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