backport to buster
[hcoop/debian/openafs.git] / src / util / fileutil.c
CommitLineData
805e021f
CE
1/*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10/* File-oriented utility functions */
11
12#include <afsconfig.h>
13#include <afs/param.h>
14#include <afs/stds.h>
15
16#include <roken.h>
17
18#include <stddef.h>
19
20#ifdef AFS_NT40_ENV
21#include "errmap_nt.h"
22#endif
23
24#include "fileutil.h"
25
26/*
27 * FilepathNormalizeEx() -- normalize file path; i.e., use only forward (or only
28 * backward) slashes, remove multiple and trailing slashes.
29 */
30void
31FilepathNormalizeEx(char *path, int slashType)
32{
33 short bWasSlash = 0;
34 char *pP, *pCopyFrom;
35 char slash = '/'; /* Default to forward slashes */
36
37 if (slashType == FPN_BACK_SLASHES)
38 slash = '\\';
39
40 if (path != NULL) {
41 /* use only forward slashes; remove multiple slashes */
42 for (pP = pCopyFrom = path; *pCopyFrom != '\0'; pCopyFrom++) {
43 if ((*pCopyFrom == '/') || (*pCopyFrom == '\\')) {
44 if (!bWasSlash) {
45 *pP++ = slash;
46 bWasSlash = 1;
47 }
48 } else {
49 *pP++ = *pCopyFrom;
50 bWasSlash = 0;
51 }
52 }
53 *pP = '\0';
54
55 /* strip off trailing slash (unless specifies root) */
56 pP--;
57 if ((*pP == slash) && (pP != path)) {
58#ifdef AFS_NT40_ENV
59 /* check for "X:/" */
60 if (*(pP - 1) != ':') {
61 *pP = '\0';
62 }
63#else
64 *pP = '\0';
65#endif
66 }
67 }
68}
69
70
71void
72FilepathNormalize(char *path)
73{
74 FilepathNormalizeEx(path, FPN_FORWARD_SLASHES);
75}
76
77/* Open a file for buffered I/O */
78bufio_p
79BufioOpen(char *path, int oflag, int mode)
80{
81 bufio_p bp;
82
83 bp = malloc(sizeof(bufio_t));
84 if (bp == NULL) {
85 return NULL;
86 }
87#ifdef AFS_NT40_ENV
88 bp->fd = _open(path, oflag, mode);
89#else
90 bp->fd = open(path, oflag, mode);
91#endif
92 if (bp->fd == BUFIO_INVALID_FD) {
93 free(bp);
94 return NULL;
95 }
96
97 bp->pos = 0;
98 bp->len = 0;
99 bp->eof = 0;
100
101 return bp;
102}
103
104/* Read the next line of a file up to len-1 bytes into buf,
105 * and strip off the carriage return. buf is null terminated.
106 * Returns -1 on EOF or error, length of string on success.
107 */
108int
109BufioGets(bufio_p bp, char *buf, int buflen)
110{
111 int rc;
112 char c;
113 int tlen, pos, len;
114
115 if (!buf || buflen <= 1 || !bp || bp->eof) {
116 return -1;
117 }
118
119 tlen = 0;
120 pos = bp->pos;
121 len = bp->len;
122 while (1) {
123 if (pos >= len) {
124#ifdef AFS_NT40_ENV
125 rc = _read(bp->fd, bp->buf, BUFIO_BUFSIZE);
126#else
127 rc = read(bp->fd, bp->buf, BUFIO_BUFSIZE);
128#endif
129 if (rc < 0) {
130 bp->eof = 1;
131 return -1;
132 } else if (rc == 0) {
133 bp->eof = 1;
134 if (tlen == 0) {
135 return -1;
136 } else {
137 return tlen;
138 }
139 }
140 pos = bp->pos = 0;
141 len = bp->len = rc;
142 }
143 while (pos < len) {
144 c = bp->buf[pos++];
145 if (c == '\n') {
146 buf[tlen] = '\0';
147 bp->pos = pos;
148 bp->len = len;
149 return tlen;
150 } else {
151 buf[tlen++] = c;
152 if (tlen >= buflen - 1) {
153 buf[tlen] = '\0';
154 bp->pos = pos;
155 bp->len = len;
156 return tlen;
157 }
158 }
159 }
160 }
161}
162
163/* Close a buffered I/O handle */
164int
165BufioClose(bufio_p bp)
166{
167 BUFIO_FD fd;
168 int rc;
169
170 if (!bp) {
171 return -1;
172 }
173 fd = bp->fd;
174 free(bp);
175#ifdef AFS_NT40_ENV
176 rc = _close(fd);
177#else
178 rc = close(fd);
179#endif
180
181 return rc;
182}