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