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

📄 file.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 2 页
字号:
    FILE *	stream){    int	ch;    char *line = alloc(AGETS_LINE_INCR);    size_t line_size = 0;    size_t loffset = 0;    int	inquote = 0;    int	escape = 0;    (void)sourcefile;	/* Quiet unused parameter warning if not debugging */    (void)lineno;	/* Quiet unused parameter warning if not debugging */    while ((ch = fgetc(stream)) != EOF) {	if (ch == '\n') {	    if (!inquote) {		if (escape) {		    escape = 0;		    loffset--;	/* Consume escape in buffer */		    continue;		}		/* Reached end of line so exit without passing on LF */		break;	    }	}	if (ch == '\\') {	    escape = 1;	} else {	    if (ch == '"') {		if (!escape) 		    inquote = !inquote;	    }	    escape = 0;	}	if ((loffset + 1) >= line_size) {	    char *tmpline;	    /*	     * Reallocate input line.	     * alloc() never return NULL pointer.	     */	    tmpline = alloc(line_size + AGETS_LINE_INCR);	    memcpy(tmpline, line, line_size);	    amfree(line);	    line = tmpline;	    line_size = line_size + AGETS_LINE_INCR;	}	line[loffset++] = (char)ch;    }    if ((ch == EOF) && (loffset == 0)) {	amfree(line); /* amfree zeros line... */    } else {	line[loffset] = '\0';    }    /*     * Return what we got even if there was not a newline.     * Only report done (NULL) when no data was processed.     */    return line;}/* *===================================================================== * Find/create a buffer for a particular file descriptor for use with * areads(). * * void areads_getbuf (const char *file, size_t line, int fd) * * entry:	file, line = caller source location *		fd = file descriptor to look up * exit:	returns a pointer to the buffer, possibly new *===================================================================== */static struct areads_buffer {    char *buffer;    char *endptr;    size_t bufsize;} *areads_buffer = NULL;static int areads_bufcount = 0;static size_t areads_bufsize = BUFSIZ;		/* for the test program */static voidareads_getbuf(    const char *s,    int		l,    int		fd){    struct areads_buffer *new;    size_t size;    assert(fd >= 0);    if(fd >= areads_bufcount) {	size = (size_t)(fd + 1) * SIZEOF(*areads_buffer);	new = (struct areads_buffer *) debug_alloc(s, l, size);	memset((char *)new, 0, size);	if(areads_buffer) {	    size = areads_bufcount * SIZEOF(*areads_buffer);	    memcpy(new, areads_buffer, size);	}	amfree(areads_buffer);	areads_buffer = new;	areads_bufcount = fd + 1;    }    if(areads_buffer[fd].buffer == NULL) {	areads_buffer[fd].bufsize = areads_bufsize;	areads_buffer[fd].buffer = debug_alloc(s, l,					       areads_buffer[fd].bufsize + 1);	areads_buffer[fd].buffer[0] = '\0';	areads_buffer[fd].endptr = areads_buffer[fd].buffer;    }}/* *===================================================================== * Return the amount of data still in an areads buffer. * * ssize_t areads_dataready (int fd) * * entry:	fd = file descriptor to release buffer for * exit:	returns number of bytes of data ready to process *===================================================================== */ssize_tareads_dataready(    int	fd){    ssize_t r = 0;    if(fd >= 0 && fd < areads_bufcount && areads_buffer[fd].buffer != NULL) {	r = (ssize_t) (areads_buffer[fd].endptr - areads_buffer[fd].buffer);    }    return r;}/* *===================================================================== * Release a buffer for a particular file descriptor used by areads(). * * void areads_relbuf (int fd) * * entry:	fd = file descriptor to release buffer for * exit:	none *===================================================================== */voidareads_relbuf(    int fd){    if(fd >= 0 && fd < areads_bufcount) {	amfree(areads_buffer[fd].buffer);	areads_buffer[fd].endptr = NULL;	areads_buffer[fd].bufsize = 0;    }}/* *===================================================================== * Get the next line of input from a file descriptor. * * char *areads (int fd) * * entry:	fd = file descriptor to read * exit:	returns a pointer to an alloc'd string or NULL at EOF *		or error (errno will be zero on EOF). * * Notes:	the newline, if read, is removed from the string *		the caller is responsible for free'ing the string *===================================================================== */char *debug_areads (    const char *s,    int		l,    int		fd){    char *nl;    char *line;    char *buffer;    char *endptr;    char *newbuf;    size_t buflen;    size_t size;    ssize_t r;    if(fd < 0) {	errno = EBADF;	return NULL;    }    areads_getbuf(s, l, fd);    buffer = areads_buffer[fd].buffer;    endptr = areads_buffer[fd].endptr;    buflen = areads_buffer[fd].bufsize - (size_t)(endptr - buffer);    while((nl = strchr(buffer, '\n')) == NULL) {	/*	 * No newline yet, so get more data.	 */	if (buflen == 0) {	    if ((size = areads_buffer[fd].bufsize) < 256 * areads_bufsize) {		size *= 2;	    } else {		size += 256 * areads_bufsize;	    }	    newbuf = debug_alloc(s, l, size + 1);	    memcpy (newbuf, buffer, areads_buffer[fd].bufsize + 1);	    amfree(areads_buffer[fd].buffer);	    areads_buffer[fd].buffer = newbuf;	    areads_buffer[fd].endptr = newbuf + areads_buffer[fd].bufsize;	    areads_buffer[fd].bufsize = size;	    buffer = areads_buffer[fd].buffer;	    endptr = areads_buffer[fd].endptr;	    buflen = areads_buffer[fd].bufsize - (size_t)(endptr - buffer);	}	if ((r = read(fd, endptr, buflen)) <= 0) {	    if(r == 0) {		errno = 0;		/* flag EOF instead of error */	    }	    return NULL;	}	endptr[r] = '\0';		/* we always leave room for this */	endptr += r;	buflen -= r;    }    *nl++ = '\0';    line = stralloc(buffer);    size = (size_t)(endptr - nl);	/* data still left in buffer */    memmove(buffer, nl, size);    areads_buffer[fd].endptr = buffer + size;    areads_buffer[fd].endptr[0] = '\0';    return line;}int robust_open(const char * pathname, int flags, mode_t mode) {    int result = -1;    int e_busy_count = 0;    for (;;) {        if (flags & O_CREAT) {            result = open(pathname, flags, mode);        } else {            result = open(pathname, flags);        }        if (result < 0) {#ifdef EBUSY            /* EBUSY is a tricky one; sometimes it is synonymous with               EINTR, but sometimes it means the device is open               elsewhere (e.g., with a tape drive on Linux). We take               the middle path and retry, but with limited               patience. */            if (errno == EBUSY && e_busy_count < 10) {                e_busy_count ++;                continue;            } else#endif            if (0                /* Always retry on EINTR; if the caller did                   not specify non-blocking mode, then also retry on                   EAGAIN or EWOULDBLOCK. */#ifdef EINTR                || errno == EINTR#endif                || ( 1#ifdef O_NONBLOCK                  && !(flags & O_NONBLOCK)#endif                  && ( 0#ifdef EAGAIN                       || errno == EAGAIN#endif#ifdef EWOULDBLOCK                       || errno == EWOULDBLOCK#endif                       ) ) ) {                /* Try again */                continue;            } else {                /* Failure. */                return result;            }        } else {            break;        }    }#ifdef F_SETFD    if (result >= 0) {        fcntl(result, F_SETFD, 1); /* Throw away result. */    }#endif    return result;}int robust_close(int fd) {    for (;;) {        int result;        result = close(fd);        if (result != 0 && (0#ifdef EINTR                            || errno == EINTR#endif#ifdef EBUSY                            || errno == EBUSY#endif#ifdef EAGAIN                            || errno == EAGAIN#endif#ifdef EWOULDBLOCK                            || errno == EWOULDBLOCK#endif                            )) {            continue;        } else {            return result;        }    }}uid_tget_client_uid(void){    static uid_t client_uid = (uid_t) -1;    struct passwd      *pwent;    if(client_uid == (uid_t) -1 && (pwent = getpwnam(CLIENT_LOGIN)) != NULL) {	client_uid = pwent->pw_uid;	endpwent();    }    return client_uid;}gid_tget_client_gid(void){    static gid_t client_gid = (gid_t) -1;    struct passwd      *pwent;    if(client_gid == (gid_t) -1 && (pwent = getpwnam(CLIENT_LOGIN)) != NULL) {	client_gid = pwent->pw_gid;	endpwent();    }    return client_gid;}char *get_original_cwd(void){    if (original_cwd == NULL) {	original_cwd = g_get_current_dir();    }    return original_cwd;}#ifdef TESTintmain(    int		argc,    char **	argv){	int rc;	int fd;	char *name;	char *top;	char *file;	char *line;	/*	 * Configure program for internationalization:	 *   1) Only set the message locale for now.	 *   2) Set textdomain for all amanda related programs to "amanda"	 *      We don't want to be forced to support dozens of message catalogs	 */  	setlocale(LC_MESSAGES, "C");	textdomain("amanda"); 	safe_fd(-1, 0);	set_pname("file test");	dbopen(NULL);	/* Don't die when child closes pipe */	signal(SIGPIPE, SIG_IGN);	name = "/tmp/a/b/c/d/e";	if (argc > 2 && argv[1][0] != '\0') {		name = argv[1];	}	top = "/tmp";	if (argc > 3 && argv[2][0] != '\0') {		name = argv[2];	}	file = "/etc/hosts";	if (argc > 4 && argv[3][0] != '\0') {		name = argv[3];	}	g_fprintf(stderr, _("Create parent directories of %s ..."), name);	rc = mkpdir(name, (mode_t)02777, (uid_t)-1, (gid_t)-1);	if (rc == 0)		g_fprintf(stderr, " done\n");	else {		perror(_("failed"));		return rc;	}	g_fprintf(stderr, _("Delete %s back to %s ..."), name, top);	rc = rmpdir(name, top);	if (rc == 0)		g_fprintf(stderr, _(" done\n"));	else {		perror(_("failed"));		return rc;	}	g_fprintf(stderr, _("areads dump of %s ..."), file);	if ((fd = open (file, 0)) < 0) {		perror(file);		return 1;	}	areads_bufsize = 1;			/* force buffer overflow */	while ((line = areads(fd)) != NULL) {		puts(line);		amfree(line);	}	aclose(fd);	g_fprintf(stderr, _(" done.\n"));	g_fprintf(stderr, _("Finished.\n"));	return 0;}#endif

⌨️ 快捷键说明

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