Include "rpm-qa" file.
[nethome.git] / src / wcr.c
1 #define _LARGEFILE64_SOURCE 1
2
3 #include <stdio.h>
4 #include <errno.h>
5 #include <fcntl.h>
6 #include <stdlib.h>
7 #include <limits.h>
8 #include <unistd.h>
9 #include <time.h>
10 #include <string.h>
11 #include <stdarg.h>
12
13 #define DEF_BLOCK 1024
14
15 #ifndef LLONG_MAX
16 #   define LLONG_MAX    9223372036854775807LL
17 #endif
18
19 char *pname;
20
21 static void msg(const char *fmt,...)
22 {
23 va_list ap;
24 time_t tm=time(NULL);
25 char *ts=ctime(&tm),*s;
26
27         if ((s=strchr(ts,'\n'))) *s='\0';
28         fprintf(stderr,"%s: %s - ",pname,ts);
29         va_start(ap,fmt);
30         vfprintf(stderr,fmt,ap);
31         va_end(ap);
32         fputc('\n',stderr);
33 }
34
35 int main(int argc,char **argv)
36 {
37 int block=DEF_BLOCK,r,fd;
38 char *buf;
39 long long offs=0,offs2=0,totsize=-1,forcedsize=0;
40
41         pname=argv[0];
42         if (argc>1) {
43                 if ((fd=open(argv[1],O_RDONLY
44 #ifdef O_BINARY
45                 |O_BINARY
46 #endif
47                 ))==-1) {
48                         msg("open(\"%s\") error: %m",argv[1]);
49                         return(EXIT_FAILURE);
50                         }
51                 if (argc>2) {
52                         block=atoi(argv[2]);
53                         if (block<1||block>=INT_MAX) {
54                                 block=DEF_BLOCK;
55                                 msg("Forced block size %d",block);
56                                 }
57                         }
58                 if (argc>3) {
59                         forcedsize=atoll(argv[3]);
60                         if (forcedsize<1||forcedsize>=LLONG_MAX) {
61                                 forcedsize=0;
62                                 msg("Total size NOT forced");
63                                 }
64                         }
65                 }
66         else fd=STDIN_FILENO;
67         if (!(buf=malloc(block))) {
68                 msg("Error allocating buffer, size=%d",block);
69                 return(EXIT_FAILURE);
70                 }
71         if (!(totsize=forcedsize)) {
72                 if ((totsize=lseek64(fd,0,SEEK_END))>0) {
73                         if ((offs2=lseek64(fd,0,SEEK_SET)))
74                                 msg("Error back-lseek64(0,SEEK_SET)=%Ld: %m",offs2);
75                         }
76                 }
77         if (totsize)
78                 msg("Starting, size=%Ld...",totsize);
79         else
80                 msg("Starting, size unknown...",totsize);
81
82         while (errno=0,(r=read(fd,buf,block))) {
83                 if (r<0) {
84                         msg("read %Ld:%Ld(%u): %m",offs,offs+block,block);
85                         if (fd==STDIN_FILENO) {
86                                 msg("Error skipping from stdin not supported!");
87                                 return(EXIT_FAILURE);
88                                 }
89                         offs+=block;
90                         if ((offs2=lseek64(STDIN_FILENO,offs,SEEK_SET))!=offs) { /* FIXME */
91                                 msg("Error recovery lseek64(%Ld,SEEK_SET)=%Ld: %m",offs,offs2);
92                                 return(EXIT_FAILURE);
93                                 }
94                         continue;
95                         }
96                 offs+=r;
97                 printf("%Ld",offs);
98                 if (totsize>0) printf("/%Ld",totsize);
99                 putchar('\r');
100                 fflush(stdout);
101                 }
102         msg("Finished, total read %Ld.",offs);
103         return(EXIT_SUCCESS);
104 }