Commit | Line | Data |
---|---|---|
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 | */ | |
30 | void | |
31 | FilepathNormalizeEx(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 | ||
71 | void | |
72 | FilepathNormalize(char *path) | |
73 | { | |
74 | FilepathNormalizeEx(path, FPN_FORWARD_SLASHES); | |
75 | } | |
76 | ||
77 | /* Open a file for buffered I/O */ | |
78 | bufio_p | |
79 | BufioOpen(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 | */ | |
108 | int | |
109 | BufioGets(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 */ | |
164 | int | |
165 | BufioClose(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 | } |