1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <sys/ioctl.h>
5 #include <unistd.h>
6 #include <ctype.h>
7 #include <string.h>
8
9 #define CDPARANOIA_OUTPUT_BUF_LENGTH 1024
10 #define CDPARANOIA_OUTPUT_LINE_LENGTH 74
11 #define CDPARANOIA_STAT_LENGTH 42
12 #define CDPARANOIA_GRAPH_LENGTH 30
13
14 #define PRINTOUT_INTERVAL 0.5
15
16 extern int errno;
17 int cdparanoia_read_stat (unsigned *current, char **graph_string);
18 int find_cdparanoia_output_read_offset (char *buf, int begin, int end);
19 void print_msg (int begin, int length, int current, char *graph);
20
21 int
cdparanoia_read_stat(unsigned * current,char ** graph_string)22 cdparanoia_read_stat (unsigned *current, char **graph_string)
23 {
24 extern int errno;
25 static char buf[CDPARANOIA_OUTPUT_BUF_LENGTH];
26 static char status[CDPARANOIA_STAT_LENGTH + 1];
27 static char graph[CDPARANOIA_GRAPH_LENGTH + 1];
28 ssize_t bytes_read;
29 int bytes_avail;
30 static int prev_bytes_avail = -1;
31 int read_offset, temp_offset, count;
32
33 ioctl (0, FIONREAD, &bytes_avail);
34 if (bytes_avail < 4 * CDPARANOIA_OUTPUT_LINE_LENGTH) {
35 if (bytes_avail == prev_bytes_avail)
36 /* nothing available, let's wait */
37 return -1;
38 else {
39 /* Record available bytes, and let's just wait */
40 prev_bytes_avail = bytes_avail;
41 return -1;
42 }
43 }
44 prev_bytes_avail = -1;
45
46 count = 0;
47 do {
48 bytes_read = read (0, (void *) buf, sizeof (buf));
49 temp_offset = bytes_read - 4 * CDPARANOIA_OUTPUT_LINE_LENGTH - 1;
50 read_offset = find_cdparanoia_output_read_offset (buf,
51 temp_offset,
52 sizeof (buf) - 1);
53 if (read_offset < 0
54 || read_offset > sizeof (buf) - CDPARANOIA_OUTPUT_LINE_LENGTH) {
55 if (count == 0)
56 return -1;
57 else
58 break;
59 }
60
61 strncpy (status, buf + read_offset, sizeof (status));
62 status[sizeof (status) - 1] = '\0';
63 count++;
64 } while (bytes_read == sizeof (buf));
65
66 strncpy (graph, status, sizeof (graph));
67 graph[sizeof (graph) - 1] = '\0';
68 *graph_string = graph;
69
70 temp_offset = CDPARANOIA_GRAPH_LENGTH + 1;
71
72 sscanf (status + temp_offset + 1, "%u", current);
73
74 return 0;
75 }
76
77 int
find_cdparanoia_output_read_offset(char * buf,int begin,int end)78 find_cdparanoia_output_read_offset (char *buf, int begin, int end)
79 {
80 int i;
81
82 i = begin;
83
84 do {
85 while (buf[i] != '=' && i <= end - 16)
86 i++;
87
88 if (buf[i + 3] == 'P'
89 && isdigit (buf[i + 16 + CDPARANOIA_GRAPH_LENGTH + 3]))
90 return i + 16;
91 else
92 i++;
93 } while (i <= end - 16);
94 return -1;
95 }
96
97 // print out [P 0.xxxx "----> "]\n
98 void
print_msg(int begin,int length,int current,char * graph)99 print_msg (int begin, int length, int current, char *graph)
100 {
101 printf ("[P ");
102 printf ("%f ", (double) (current - begin) / (double) length);
103 printf ("\"%s\"]\n", graph);
104 }
105
106 int
main(int argc,char ** argv)107 main (int argc, char **argv)
108 {
109 int begin, length;
110 int current;
111 char *graph_string;
112
113 if (argc != 3) {
114 fprintf (stderr, "This is ripperX plugin for cdparanoia. Syntax is\n"
115 "ripperX_plugin-cdparanoia beginning_sector length_in_sector\n");
116 exit (1);
117 }
118
119 sscanf (argv[1], "%d", &begin);
120 sscanf (argv[2], "%d", &length);
121
122 while (1) {
123 if (cdparanoia_read_stat (¤t, &graph_string) == 0)
124 print_msg (begin, length, current, graph_string);
125 usleep (PRINTOUT_INTERVAL * 1000000);
126 }
127 }
128