1 /* cdrdao - write audio CD-Rs in disc-at-once mode
2 *
3 * Copyright (C) 1998-2001 Andreas Mueller <andreas@daneb.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <config.h>
21
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <limits.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <stdarg.h>
31
32 #include "util.h"
33 #include "Sample.h"
34
strdupCC(const char * s)35 char *strdupCC(const char *s)
36 {
37 char *ret;
38 long len;
39
40 if (s == NULL) {
41 return NULL;
42 }
43
44 len = strlen(s);
45
46 ret = new char[len + 1];
47
48 strcpy(ret, s);
49
50 return ret;
51 }
52
strdup3CC(const char * s1,const char * s2,const char * s3)53 char *strdup3CC(const char *s1, const char *s2, const char *s3)
54 {
55 char *ret;
56 long len = 0;
57
58 if (s1 == NULL && s2 == NULL && s3 == NULL)
59 return NULL;
60
61 if (s1 != NULL)
62 len = strlen(s1);
63
64 if (s2 != NULL)
65 len += strlen(s2);
66
67 if (s3 != NULL)
68 len += strlen(s3);
69
70 ret = new char[len + 1];
71
72 *ret = 0;
73
74 if (s1 != NULL)
75 strcpy(ret, s1);
76
77 if (s2 != NULL)
78 strcat(ret, s2);
79
80 if (s3 != NULL)
81 strcat(ret, s3);
82
83 return ret;
84 }
85
strdupvCC(const char * s1,...)86 char *strdupvCC(const char *s1, ...)
87 {
88 const char *p;
89 char *ret;
90 long len;
91 va_list ap;
92
93 if (s1 == NULL)
94 return NULL;
95
96 len = strlen(s1);
97
98 va_start(ap, s1);
99
100 while ((p = va_arg(ap, const char *)) != NULL)
101 len += strlen(p);
102
103 va_end(ap);
104
105 ret = new char[len + 1];
106
107 strcpy(ret, s1);
108
109
110 va_start(ap, s1);
111
112 while ((p = va_arg(ap, const char *)) != NULL)
113 strcat(ret, p);
114
115 va_end(ap);
116
117 return ret;
118 }
119
fullRead(int fd,void * buf,long count)120 long fullRead(int fd, void *buf, long count)
121 {
122 long n = 0;
123 long nread = 0;
124
125 do {
126 do {
127 n = read(fd, (char *)buf + nread, count);
128 } while (n < 0 && (errno == EAGAIN || errno == EINTR));
129
130 if (n < 0) {
131 return -1;
132 }
133
134 if (n == 0) {
135 return nread;
136 }
137
138 count -= n;
139 nread += n;
140 } while (count > 0);
141
142 return nread;
143 }
144
fullWrite(int fd,const void * buf,long count)145 long fullWrite(int fd, const void *buf, long count)
146 {
147 long n;
148 long nwritten = 0;
149 const char *p = (const char *)buf;
150
151 do {
152 do {
153 n = write(fd, p, count);
154 } while (n < 0 && (errno == EAGAIN || errno == EINTR));
155
156 if (n < 0)
157 return -1;
158
159 if (n == 0)
160 return nwritten;
161
162 count -= n;
163 nwritten += n;
164 p += n;
165 } while (count > 0);
166
167 return nwritten;
168 }
169
readLong(FILE * fp)170 long readLong(FILE *fp)
171 {
172 unsigned char c1 = getc(fp);
173 unsigned char c2 = getc(fp);
174 unsigned char c3 = getc(fp);
175 unsigned char c4 = getc(fp);
176
177 return ((long)c4 << 24) | ((long)c3 << 16) | ((long)c2 << 8) | (long)c1;
178 }
179
readShort(FILE * fp)180 short readShort(FILE *fp)
181 {
182 unsigned char c1 = getc(fp);
183 unsigned char c2 = getc(fp);
184
185 return ((short)c2 << 8) | (short)c1;
186 }
187
swapSamples(Sample * buf,unsigned long len)188 void swapSamples(Sample *buf, unsigned long len)
189 {
190 unsigned long i;
191
192 for (i = 0; i < len; i++) {
193 buf[i].swap();
194 }
195 }
196
int2bcd(int d)197 unsigned char int2bcd(int d)
198 {
199 if (d >= 0 && d <= 99)
200 return ((d / 10) << 4) | (d % 10);
201 else
202 return d;
203 }
204
bcd2int(unsigned char d)205 int bcd2int(unsigned char d)
206 {
207 unsigned char d1 = d & 0x0f;
208 unsigned char d2 = d >> 4;
209
210 if (d1 <= 9 && d2 <= 9) {
211 return d2 * 10 + d1;
212 }
213 else {
214 return d;
215 }
216 }
217
stripCwd(const char * fname)218 const char *stripCwd(const char *fname)
219 {
220 static char *buf = NULL;
221 static long bufLen = 0;
222
223 char cwd[PATH_MAX + 1];
224 long len;
225
226 if (fname == NULL)
227 return NULL;
228
229 len = strlen(fname);
230
231 if (buf == NULL || len >= bufLen) {
232 bufLen = len + 1;
233 delete[] buf;
234 buf = new char[bufLen];
235 }
236
237 if (getcwd(cwd, PATH_MAX + 1) == NULL) {
238 // if we cannot retrieve the current working directory return 'fname'
239 strcpy(buf, fname);
240 }
241 else {
242 len = strlen(cwd);
243
244 if (strncmp(cwd, fname, len) == 0) {
245 if (*(fname + len) == '/')
246 strcpy(buf, fname + len + 1);
247 else
248 strcpy(buf, fname + len);
249
250 if (buf[0] == 0) {
251 // resulting filename would be "" -> return 'fname'
252 strcpy(buf, fname);
253 }
254 }
255 else {
256 strcpy(buf, fname);
257 }
258 }
259
260 return buf;
261 }
262
fileExtension(const char * fname)263 FileExtension fileExtension(const char* fname)
264 {
265 const char* e;
266
267 if (fname && (e = strrchr(fname, '.'))) {
268 e++;
269
270 if (strcasecmp(e, "toc") == 0)
271 return FE_TOC;
272 if (strcasecmp(e, "cue") == 0)
273 return FE_CUE;
274 if (strcasecmp(e, "wav") == 0)
275 return FE_WAV;
276 if (strcasecmp(e, "mp3") == 0)
277 return FE_MP3;
278 if (strcasecmp(e, "ogg") == 0)
279 return FE_OGG;
280 if (strcasecmp(e, "m3u") == 0)
281 return FE_M3U;
282 }
283
284 return FE_UNKNOWN;
285 }
286
resolveFilename(std::string & abs,const char * file,const char * path)287 bool resolveFilename(std::string& abs, const char* file, const char* path)
288 {
289 struct stat st;
290
291 // First checks if file is already absolute, in which case we do
292 // nothing.
293 if (file[0] == '/') {
294 abs = file;
295 return true;
296 }
297
298 // Now checks if file is readable in current directory. Current
299 // directory has precedence over search path.
300 if (stat(file, &st) == 0 && (st.st_mode & S_IFREG)) {
301 char cwd[1024];
302 if (getcwd(cwd, 1024)) {
303 abs = cwd;
304 abs += "/";
305 }
306 abs += file;
307 return true;
308 }
309
310 // Now check in search path.
311 std::string afile = path;
312 if (*(afile.end()) != '/')
313 afile += "/";
314 afile += file;
315 if (stat(afile.c_str(), &st) == 0 && (st.st_mode & S_IFREG)) {
316 abs = afile;
317 return true;
318 }
319
320 // File not found.
321 abs = "";
322 return false;
323 }
324