1 /*
2 Copyright (C) 2004, 2008, 2010-2011, 2017 Rocky Bernstein <rocky@gnu.org>
3 Copyright (C) 2014 Robert Kausch <robert.kausch@freac.org>
4 Copyright (C) 1998 Monty xiphmont@mit.edu
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 # define __CDIO_CONFIG_H__ 1
23 #endif
24
25 #ifdef HAVE_SYS_TIME_H
26 # include <sys/time.h>
27 #endif
28
29 #include "common_interface.h"
30 #include "utils.h"
31 void
cderror(cdrom_drive_t * d,const char * s)32 cderror(cdrom_drive_t *d,const char *s)
33 {
34 ssize_t bytes_ret __attribute__((unused));
35 if(s && d){
36 switch(d->errordest){
37 case CDDA_MESSAGE_PRINTIT:
38 bytes_ret = write(STDERR_FILENO, s, strlen(s));
39 if (strlen(s) != bytes_ret)
40
41 break;
42 case CDDA_MESSAGE_LOGIT:
43 d->errorbuf=catstring(d->errorbuf,s);
44 break;
45 case CDDA_MESSAGE_FORGETIT:
46 default:
47 break;
48 }
49 }
50 }
51
52 void
cdmessage(cdrom_drive_t * d,const char * s)53 cdmessage(cdrom_drive_t *d, const char *s)
54 {
55 ssize_t bytes_ret __attribute__((unused));
56 if(s && d){
57 switch(d->messagedest){
58 case CDDA_MESSAGE_PRINTIT:
59 bytes_ret = write(STDERR_FILENO, s, strlen(s));
60 break;
61 case CDDA_MESSAGE_LOGIT:
62 d->messagebuf=catstring(d->messagebuf,s);
63 break;
64 case CDDA_MESSAGE_FORGETIT:
65 default:
66 break;
67 }
68 }
69 }
70
71 void
idperror(int messagedest,char ** messages,const char * f,const char * s)72 idperror(int messagedest,char **messages,const char *f,
73 const char *s)
74 {
75
76 char *buffer;
77 int malloced=0;
78 if(!f)
79 buffer=(char *)s;
80 else
81 if(!s)
82 buffer=(char *)f;
83 else{
84 buffer=malloc(strlen(f)+strlen(s)+9);
85 sprintf(buffer,f,s);
86 malloced=1;
87 }
88
89 if(buffer){
90 ssize_t bytes_ret __attribute__((unused));
91 switch(messagedest){
92 case CDDA_MESSAGE_PRINTIT:
93 bytes_ret = write(STDERR_FILENO,buffer,strlen(buffer));
94 if(errno){
95 bytes_ret = write(STDERR_FILENO,": ",2);
96 bytes_ret = write(STDERR_FILENO,strerror(errno),strlen(strerror(errno)));
97 bytes_ret = write(STDERR_FILENO,"\n",1);
98 }
99 break;
100 case CDDA_MESSAGE_LOGIT:
101 if(messages){
102 *messages=catstring(*messages,buffer);
103 if(errno){
104 *messages=catstring(*messages,": ");
105 *messages=catstring(*messages,strerror(errno));
106 *messages=catstring(*messages,"\n");
107 }
108 }
109 break;
110 case CDDA_MESSAGE_FORGETIT:
111 default:
112 break;
113 }
114 }
115 if(malloced)free(buffer);
116 }
117
118 void
idmessage(int messagedest,char ** messages,const char * f,const char * s)119 idmessage(int messagedest,char **messages,const char *f,
120 const char *s)
121 {
122 char *buffer;
123 int malloced=0;
124 ssize_t bytes_ret __attribute__((unused));
125 if(!f)
126 buffer=(char *)s;
127 else
128 if(!s)
129 buffer=(char *)f;
130 else{
131 const unsigned int i_buffer=strlen(f)+strlen(s)+2;
132 buffer=malloc(i_buffer);
133 sprintf(buffer,f,s);
134 strncat(buffer,"\n",1);
135 malloced=1;
136 }
137
138 if(buffer) {
139 switch(messagedest){
140 case CDDA_MESSAGE_PRINTIT:
141 bytes_ret = write(STDERR_FILENO,buffer,strlen(buffer));
142 if(!malloced)
143 bytes_ret = write(STDERR_FILENO,"\n",1);
144 break;
145 case CDDA_MESSAGE_LOGIT:
146 if(messages){
147 *messages=catstring(*messages,buffer);
148 if(!malloced)*messages=catstring(*messages,"\n");
149 }
150 break;
151 case CDDA_MESSAGE_FORGETIT:
152 default:
153 break;
154 }
155 }
156 if(malloced)free(buffer);
157 }
158
159 char *
catstring(char * buff,const char * s)160 catstring(char *buff, const char *s) {
161 if (s) {
162 const unsigned int add_len = strlen(s) + 1;
163 if(buff) {
164 buff = realloc(buff, strlen(buff) + add_len);
165 } else {
166 buff=calloc(add_len, 1);
167 }
168 strncat(buff, s, add_len - 1);
169 }
170 return(buff);
171 }
172
173 int
gettime(struct timespec * ts)174 gettime(struct timespec *ts) {
175 int ret = -1;
176 if (!ts) return ret;
177
178 #if defined(HAVE_CLOCK_GETTIME)
179 /* Use clock_gettime if available, preferably using the monotonic clock.
180 */
181 static clockid_t clock = (clockid_t)-1;
182 if ((int)clock == -1) clock = (clock_gettime(CLOCK_MONOTONIC, ts) < 0 ? CLOCK_REALTIME : CLOCK_MONOTONIC);
183 ret = clock_gettime(clock, ts);
184 #elif defined(WIN32)
185 /* clock() returns wall time (not CPU time) on Windows, so we can use it here.
186 */
187 clock_t time = clock();
188 if ((int)time != -1) {
189 ts->tv_sec = time/CLOCKS_PER_SEC;
190 ts->tv_nsec = time%CLOCKS_PER_SEC*(1000000000/CLOCKS_PER_SEC);
191 ret = 0;
192 }
193 #else
194 /* In other cases use gettimeofday.
195 */
196 struct timeval tv;
197 ret = gettimeofday(&tv, NULL);
198 if (ret == 0) {
199 ts->tv_sec = tv.tv_sec;
200 ts->tv_nsec = tv.tv_usec*1000;
201 }
202 #endif
203
204 return ret;
205 }
206