69 int status = stat(
copydir, &st );
73 if ( status == 0 && ! S_ISDIR(st.st_mode) ) {
75 fprintf( stderr,
"copy dir \"%s\" is a file!\n",
copydir );
77 }
else if ( S_ISDIR(st.st_mode) &&
78 !( (st.st_uid == geteuid() && ( (st.st_mode & S_IWUSR) > 0 )) ||
79 (st.st_gid == getegid() && ( (st.st_mode & S_IWGRP) > 0 )) ||
80 ((st.st_mode & S_IWOTH) > 0) ) ) {
81 fprintf( stderr,
"copy dir \"%s\" is not accessible to me\n",
copydir );
86 if ( errno != ENOENT ) {
88 fprintf( stderr,
"accessing copy-out dir \"%s\": %s\n",
93 if ( mkdir(
copydir, 0750 ) == -1 ) {
108 if ( ch ==
'\r' )
return 0u;
109 else if ( ch ==
'\n' )
return 1u;
114#define BAUTZ(x) delete[] filename; close(input); close(out); return (x)
118 const char* fn,
const char* url,
const char*
copydir,
128 static const char* index =
"index.html";
131 const char* ptr = strstr( url,
"://" );
132 if ( ptr ==
nullptr || strlen(ptr) < 4 )
return false;
136 char *filename =
new char[ strlen(ptr) + strlen(
copydir) + strlen(index) +5 ];
137 assert( filename !=
nullptr );
139 strcat( filename,
"/" );
140 char* here = filename + strlen(filename);
141 strcat( filename, ptr+3 );
144 if ( strchr( ptr+3,
'/' ) ==
nullptr ) strcat( filename,
"/" );
147 if ( filename[strlen(filename)-1] ==
'/' ) strcat( filename, index );
150 for (
char* t = strchr(here,
'/'); t; t = strchr(t,
'/') ) {
152 if ( mkdir( filename, 0775 ) == -1 && errno != EEXIST ) {
153 fprintf( stderr,
"mkdir(%s): %s\n", filename,
strerror(errno) );
156 }
else if (
debug & 0x02 ) {
157 fprintf( stderr,
"# creating %s\n", filename );
164 int out = open( filename, O_CREAT | O_RDWR | O_TRUNC, 0664 );
166 fprintf( stderr,
"open(%s,RDWR): %s\n", filename,
strerror(errno) );
169 }
else if (
debug & 0x02 ) {
170 fprintf( stderr,
"# creating %s\n", filename );
174 int input = open( fn, O_RDONLY );
176 fprintf( stderr,
"open(%s,RDONLY): %s\n", fn,
strerror(errno) );
194 static unsigned table[4][3] = { {3,2,0}, {0,4,0}, {1,4,0}, {4,2,0} };
201 state = table[ state ][
xlate(*s) ];
207 fprintf( stderr,
"WARNING: %s will contain partial HTTP header data!\n",
215 if ( filesize - metasize <= 0 ) {
216 BAUTZ( filesize-metasize == 0 );
219#ifdef USE_REGULAR_COPY
221 if ( lseek( input, metasize, SEEK_SET ) == -1 ) {
222 fprintf( stderr,
"lseek(%s,%lu): %s\n", fn, metasize,
strerror(errno) );
229 while ( (rsize=read(input,buffer,
sizeof(buffer))) > 0 ) {
230 if ( (wsize=write(out,buffer,rsize)) <= 0 )
break;
232 if ( rsize < 0 || wsize < 0 ) perror(
"while copying" );
236 off_t position = lseek( out, filesize-metasize-1, SEEK_SET );
237 if ( position == -1 ) {
238 fprintf( stderr,
"lseek(%s,%lu): %s\n", filename,
239 (
unsigned long)filesize-metasize,
242 }
else if (
debug & 0x02 ) {
243 fprintf( stderr,
"# filesize=%lu, metasize=%lu, filepos=%ld\n",
244 (
unsigned long)filesize, (
unsigned long)metasize,
249 if ( write( out,
"", 1 ) != 1 ) {
250 perror(
"write to output" );
255 const auto src =
static_cast<char *
>(mmap(
nullptr, filesize, PROT_READ,
MAP_FILE | MAP_SHARED, input, 0));
256 if (src ==
reinterpret_cast<const char *
>(-1)) {
257 perror(
"mmap input" );
262 auto dst =
static_cast<char *
>(mmap(
nullptr, filesize-metasize, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED, out, 0));
263 if (dst ==
reinterpret_cast<char *
>(-1)) {
264 perror(
"mmap output" );
265 munmap( src, filesize );
270 memcpy( dst, src+metasize, filesize-metasize );
273 munmap( dst, filesize-metasize );
274 munmap( src, filesize );
void debug(const char *format,...)
int assert_copydir(const char *copydir)
bool copy_out(size_t filesize, size_t metasize, unsigned debug, const char *fn, const char *url, const char *copydir, bool copyHdr)