/* Read len bytes from the cache file and add them to buf. */ static krb5_error_code load_bytes(krb5_context context, krb5_ccache id, size_t len, struct k5buf *buf) { void *ptr; ptr = k5_buf_get_space(buf, len); return (ptr == NULL) ? ENOMEM : read_bytes(context, id, ptr, len); }
/* * Get a line from the ACL file. Lines ending with \ are continued on the next * line. The caller should set *lineno to 1 and *incr to 0 before the first * call. On successful return, *lineno will be the line number of the line * read. Return a pointer to the line on success, or NULL on end of file or * read failure. */ static char * get_line(FILE *fp, const char *fname, int *lineno, int *incr) { const int chunksize = 128; struct k5buf buf; size_t old_len; char *p; /* Increment *lineno by the number of newlines from the last line. */ *lineno += *incr; *incr = 0; k5_buf_init_dynamic(&buf); for (;;) { /* Read at least part of a line into the buffer. */ old_len = buf.len; p = k5_buf_get_space(&buf, chunksize); if (p == NULL) return NULL; if (fgets(p, chunksize, fp) == NULL) { /* We reached the end. Return a final unterminated line, if there * is one and it's not a comment. */ k5_buf_truncate(&buf, old_len); if (buf.len > 0 && *(char *)buf.data != '#') return buf.data; k5_buf_free(&buf); return NULL; } /* Set the buffer length based on the actual amount read. */ k5_buf_truncate(&buf, old_len + strlen(p)); p = buf.data; if (buf.len > 0 && p[buf.len - 1] == '\n') { /* We have a complete raw line in the buffer. */ (*incr)++; k5_buf_truncate(&buf, buf.len - 1); if (buf.len > 0 && p[buf.len - 1] == '\\') { /* This line has a continuation marker; keep reading. */ k5_buf_truncate(&buf, buf.len - 1); } else if (buf.len == 0 || *p == '#') { /* This line is empty or a comment. Start over. */ *lineno += *incr; *incr = 0; k5_buf_truncate(&buf, 0); } else { return buf.data; } } } }