/*
* hoz - Hacha Open Zource
* Copyright (C) 2004 Gustavo Picon (http://hoz.sourceforge.net/)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#if defined(WIN32)
#define HOZ_PATHSEP '\\'
#else
#define HOZ_PATHSEP '/'
#endif
#include "hoz.h"
char outpath[MAXLEN];
size_t fullsize, partsize, headersize;
int showprogress, forceow, simulate;
/**
* hoz_echo - displays something based on a code
* @code: the event code
* @xtra: extra information about an event
*
* not all the events have a xtra parameter
*/
void hoz_echo(const int code, const char *xtra)
{
char foo[1024];
foo[0] = 0;
switch (code) {
case 301:
hoz_print(HOZ_COPYRIGHT1);
hoz_lf();
hoz_print(HOZ_COPYRIGHT2);
hoz_lf();
break;
case 401:
hoz_echo(301, NULL);
hoz_lf();
sprintf(foo, HOZ_USAGE_1, xtra);
hoz_print(foo);
hoz_lf();
hoz_print(HOZ_USAGE_2);
hoz_lf();
hoz_print(HOZ_USAGE_3);
hoz_lf();
hoz_print(HOZ_USAGE_4);
hoz_lf();
hoz_print(HOZ_USAGE_5);
hoz_lf();
hoz_print(HOZ_USAGE_6);
hoz_lf();
hoz_print(HOZ_USAGE_7);
hoz_lf();
hoz_print(HOZ_USAGE_8);
hoz_lf();
hoz_print(HOZ_USAGE_9);
hoz_lf();
break;
case 402:
/*
* it's gone
*/
break;
case 403:
hoz_lf();
hoz_print(HOZ_ENDDOTO);
hoz_lf();
break;
case 404:
hoz_lf();
sprintf(foo, HOZ_NOFILE, xtra);
hoz_print(foo);
hoz_lf();
break;
case 405:
hoz_lf();
sprintf(foo, HOZ_BADHEADER, xtra);
hoz_print(foo);
hoz_lf();
break;
case 406:
hoz_lf();
sprintf(foo, HOZ_BADPARTS, xtra);
hoz_print(foo);
hoz_lf();
break;
case 407:
hoz_lf();
sprintf(foo, HOZ_ERROPENWRITE, xtra);
hoz_print(foo);
hoz_lf();
break;
case 408:
hoz_lf();
sprintf(foo, HOZ_ERROPENREAD, xtra);
hoz_print(foo);
hoz_lf();
break;
case 409:
hoz_lf();
sprintf(foo, HOZ_ERRPARTSIZE, xtra);
hoz_print(foo);
hoz_lf();
break;
case 410:
hoz_lf();
sprintf(foo, HOZ_ERRPROCESS, xtra);
hoz_print(foo);
hoz_lf();
break;
case 411:
hoz_lf();
sprintf(foo, HOZ_ERROUTNODIR, xtra);
hoz_print(foo);
hoz_lf();
break;
case 412:
hoz_lf();
sprintf(foo, HOZ_ERRWRITE, xtra);
hoz_print(foo);
hoz_lf();
break;
case 413:
sprintf(foo, HOZ_BADARGSOPT, xtra);
hoz_print(foo);
hoz_lf();
sprintf(foo, HOZ_HMOREINFO, xtra);
hoz_print(foo);
hoz_lf();
break;
case 414:
sprintf(foo, HOZ_BADARGSFILE, xtra);
hoz_print(foo);
hoz_lf();
sprintf(foo, HOZ_HMOREINFO, xtra);
hoz_print(foo);
hoz_lf();
break;
case 415:
sprintf(foo, HOZ_HMOREINFO, xtra);
hoz_print(foo);
hoz_lf();
break;
}
}
/**
* hoz_cut_main - cut files main function
* @ifname: "file.ext" file name
*/
int hoz_cut_main(const char *ifname)
{
FILE *f_in, *f_out; /* file handles */
clock_t initime; /* to calculate the time spent */
unsigned char buf[FILESTREAMSIZE + 1], /* buffer to copy */
foo[MAXLEN], /* current 'file.n' filename */
bar[MAXLEN], /* "?????" */
baz[MAXLEN], qux; /* useless byte in the header,
* must be included for compat with hacha
*/
size_t i, /* foobar */
len, /* bytes read */
bfile, /* bytes read in current file file.n */
btotal, /* total bytes read */
dif;
double elapsed; /* total time elapsed */
char *ifnopath; /* input fname without path */
f_in = fopen(ifname, "rb");
if (!f_in) {
hoz_echo(408, NULL);
return 408;
}
i = bfile = btotal = 0;
ifnopath = hoz_nopath(ifname);
sprintf(baz, "%s.%u", ifnopath, i);
mergepath(outpath, baz, foo);
remove(foo);
f_out = fopen(foo, "ab");
if (!f_out) {
fclose(f_in);
hoz_echo(407, foo);
return 407;
}
fullsize = fsize(ifname);
/* store the time */
initime = clock();
/* begin control byte */
/*
* This code was broken, thanks Eric for reporting this
* sprintf(buf, "%u", partsize);
* len = strlen(buf);
* qux = 24 + len + strlen(ifnopath) + ((len <= 4) ? 1 : 3);
*/
sprintf(buf, "%u%u%s", partsize, fullsize, ifnopath);
qux = 20 + strlen(buf);
/* end control byte */
strcpy(bar, "?????");
sprintf(buf, "%s%c %s%s%s%u%s%u%s", bar, qux, bar,
hoz_nopath(ifname), bar, fullsize, bar, partsize, bar);
len = (size_t) strlen(buf);
buf[6] = buf[7] = buf[8] = 0;
if (fwrite(buf, sizeof(char), len, f_out) != len) {
fclose(f_in);
fclose(f_out);
hoz_echo(412, foo);
return 412;
}
sprintf(bar, HOZ_CUTTOFILE, hoz_nopath(foo));
hoz_print(bar);
for (;;) {
if (partsize <= FILESTREAMSIZE) {
len = (size_t) fread(buf, sizeof(char), FILESTREAMSIZE, f_in);
if (fwrite(buf, sizeof(char), len, f_out) != len) {
fclose(f_in);
fclose(f_out);
hoz_echo(412, foo);
return 412;
}
if (showprogress) {
hoz_print(PROGRMETERSTR); /* progress meter? */
}
bfile = len;
btotal += len;
fclose(f_out);
hoz_lf();
sprintf(bar, HOZ_PROGRESS, btotal,
fullsize,
(float) ((float) btotal / (float) fullsize) * 100);
hoz_print(bar);
hoz_lf();
if (feof(f_in)) {
break;
}
++i;
sprintf(baz, "%s.%u", ifnopath, i);
mergepath(outpath, baz, foo);
remove(foo);
f_out = fopen(foo, "ab");
if (!f_out) {
fclose(f_in);
hoz_echo(407, foo);
return 407;
}
sprintf(bar, HOZ_CUTTOFILE, hoz_nopath(foo));
hoz_print(bar);
} else {
len = (size_t) fread(buf, sizeof(char), FILESTREAMSIZE, f_in);
if (bfile + len < partsize) {
if (fwrite(buf, sizeof(char), len, f_out) != len) {
fclose(f_in);
fclose(f_out);
hoz_echo(412, foo);
return 412;
}
if (showprogress) {
hoz_print(PROGRMETERSTR); /* progress meter? */
}
bfile += len;
} else {
dif = partsize - bfile;
if (fwrite(buf, sizeof(char), dif, f_out) != dif) {
fclose(f_in);
fclose(f_out);
hoz_echo(412, foo);
return 412;
}
if (showprogress) {
hoz_print(PROGRMETERSTR); /* progress meter? */
}
bfile += dif;
fclose(f_out);
hoz_lf();
sprintf(bar, HOZ_PROGRESS, btotal,
fullsize,
(float) ((float) btotal / (float) fullsize) * 100);
hoz_print(bar);
hoz_lf();
++i;
bfile = 0;
sprintf(baz, "%s.%u", ifnopath, i);
mergepath(outpath, baz, foo);
remove(foo);
f_out = fopen(foo, "ab");
if (!f_out) {
fclose(f_in);
hoz_echo(407, foo);
return 407;
}
sprintf(bar, HOZ_CUTTOFILE, hoz_nopath(foo));
hoz_print(bar);
if (fwrite(buf + dif, sizeof(char), len - dif, f_out) !=
(len - dif)) {
fclose(f_in);
fclose(f_out);
hoz_echo(412, foo);
return 412;
}
if (showprogress) {
hoz_print(PROGRMETERSTR); /* progress meter? */
}
bfile += (len - dif);
}
btotal += len;
if (feof(f_in)) {
hoz_lf();
sprintf(bar, HOZ_PROGRESS, btotal, fullsize,
(float) ((float) btotal / (float) fullsize) * 100);
hoz_print(bar);
hoz_lf();
break;
}
}
}
sprintf(foo, "%s.%u", ifname, ++i);
remove(foo);
fclose(f_in);
fclose(f_out);
/* if the sum of the file sizes isn't the same as the original file size
* then the operation failed
*/
if (btotal != fullsize) {
sprintf(foo, "%u/%u", btotal, fullsize);
hoz_echo(410, foo);
return 410;
}
/* calculate the time spent in this operation */
elapsed = (double) (clock() - initime) / CLOCKS_PER_SEC;
elapsed = (elapsed) ? elapsed : 0.001; /* can't be 0 seconds! */
/* yes */
hoz_lf();
sprintf(bar, HOZ_CUTEND, hoz_nopath(ifname), btotal, elapsed,
(size_t) ((double) btotal / elapsed), outpath);
hoz_print(bar);
hoz_lf();
return 0;
}
/**
* hoz_paste_main - paste files main function
* @ifname: "file.0" file name
*/
int hoz_paste_main(const char *ifname)
{
FILE *f_in, *f_out; /* file handles */
clock_t initime; /* to calculate the time spent */
unsigned char buf[FILESTREAMSIZE + 1], /* buffer to copy */
foo[MAXLEN], /* current 'file.n' filename */
bar[MAXLEN], /* blah */
basename[MAXLEN], /* base filename (file.*) */
origfname[MAXLEN], *outfname;
size_t i, /* foobar */
len, /* bytes read */
bfile, /* bytes read in current file file.n */
btotal; /* total bytes read */
double elapsed; /* total time elapsed */
/* verifying that the input filename ends in ".0" */
if (ifname[strlen(ifname) - 1] != '0'
|| ifname[strlen(ifname) - 2] != '.') {
hoz_echo(403, NULL);
return 403;
}
/* error if the input file can't be opened */
f_in = fopen(ifname, "r");
if (!f_in) {
hoz_echo(404, ifname);
return 404;
}
fclose(f_in);
/* retrieving header info */
i = hoz_paste_hr(ifname, origfname);
/* if hoz_paste_hr() returns an error, end process */
if (i) {
return i;
}
/* storing the base file name, just removing the "0" from "file.0" */
strcpy(basename, ifname);
basename[strlen(basename) - 1] = 0;
/* total bytes read = 0 */
btotal = 0;
outfname =
(char *) malloc(sizeof(char) *
(strlen(origfname) + strlen(outpath) + 3));
mergepath(outpath, origfname, outfname);
/* if the file exists and !forceow, ask what to do */
if (!forceow && isfile(outfname) && !hoz_replace_ask(outfname)) {
free(outfname);
return 302;
}
/* removing the output file if it already exists */
remove(outfname);
/* opening the output file: (b)inary (w)rite */
f_out = fopen(outfname, "wb");
/* error if can't be openned */
if (!f_out) {
hoz_echo(407, outfname);
free(outfname);
return 407;
}
/* telling the user what are we doing */
hoz_lf();
sprintf(bar, HOZ_BEGINPASTE, origfname, fullsize);
hoz_print(bar);
hoz_lf();
hoz_lf();
/* store the time */
initime = clock();
for (i = 0;; i++) {
/* generating the "file.n" string, storing it in foo */
sprintf(foo, "%s%d", basename, i);
/* openning the input file: (b)inary (r)ead */
f_in = fopen(foo, "rb");
/* bytes read in file = 0 */
bfile = 0;
if (!f_in) {
break; /* last file, end */
} else {
/* extracting file.n... */
sprintf(bar, HOZ_PASTEFILE, hoz_nopath(foo));
hoz_print(bar);
if (i == 0) {
/* if we are extracting the first file (*.0),
* discard the header
*/
fread(buf, sizeof(char), headersize, f_in);
}
for (;;) {
/* appending file.n to the output file */
len =
(size_t) fread(buf, sizeof(char), FILESTREAMSIZE,
f_in);
if (len) {
if (fwrite(buf, sizeof(char), len, f_out) != len) {
fclose(f_in);
fclose(f_out);
hoz_echo(412, outfname);
free(outfname);
return 412;
}
/* fwrite(buf, sizeof(char), len, f_out); *//* argh! */
btotal += len;
bfile += len;
}
if (showprogress) {
hoz_print(PROGRMETERSTR); /* progress meter? */
}
if (feof(f_in)) {
break;
}
}
/* displays info... */
hoz_lf();
sprintf(bar, HOZ_PROGRESS, btotal,
fullsize,
(float) ((float) btotal / (float) fullsize) * 100);
hoz_print(bar);
hoz_lf();
}
/* close the file.n handle */
fclose(f_in);
if (bfile < partsize) {
/* if the current file.n file is smaller than the size defined in
* the file.0 header for a partial file, end process
*/
break;
}
}
/* close file handles */
fclose(f_out);
/* if the extracted file size isn't the same as the file defined in the
* file.0 header, then the operation failed
*/
if (btotal != fullsize) {
if (btotal < fullsize) {
hoz_lf();
sprintf(bar, HOZ_PASTEMISSING, foo);
hoz_print(bar);
hoz_lf();
}
sprintf(foo, "%u/%u", btotal, fullsize);
hoz_echo(406, foo);
free(outfname);
return 406;
}
/* calculate the time spent in this operation */
elapsed = (double) (clock() - initime) / CLOCKS_PER_SEC;
elapsed = (elapsed) ? elapsed : 0.001; /* can't be 0 seconds! */
/* yes */
hoz_lf();
sprintf(bar, HOZ_PASTEEND, origfname, btotal, elapsed,
(size_t) ((double) btotal / elapsed), outpath);
hoz_print(bar);
hoz_lf();
free(outfname);
return 0;
}
/**
* hoz_paste_hr - reads the header from the file.0 file
* @ifname: "file.0" filename
*/
int hoz_paste_hr(const char *ifname, const char *origfname)
{
int i, read, ssize;
char buf[FILESTREAMSIZE + 1], aux[MAXLEN], *foo, *bar;
FILE *f;
bar = (char *) origfname;
headersize = 0;
ssize = FILESTREAMSIZE;
if (ssize < 512) {
ssize = 512;
}
f = fopen(ifname, "rb");
read = (int) fread(buf, sizeof(char), ssize, f);
foo = buf;
if (!read || strncmp(foo, "?????", 5)) {
hoz_echo(405, ifname);
return 405;
}
foo += 5;
headersize += 5;
i = 0;
for (i = 0; *foo != '?'; foo++, i++, headersize++) {
if (i == 20) {
hoz_echo(405, ifname);
return 405;
}
}
if (strncmp(foo, "?????", 5)) {
hoz_echo(405, ifname);
return 405;
}
foo += 5;
headersize += 5;
if (*foo == '?') {
hoz_echo(405, ifname);
return 405;
}
for (i = 0; *foo != '?'; foo++, i++, headersize++) {
if (i == 255) {
hoz_echo(405, ifname);
return 405;
}
*bar++ = *foo;
}
*bar = '\0';
if (strncmp(foo, "?????", 5)) {
hoz_echo(405, ifname);
return 405;
}
foo += 5;
headersize += 5;
if (*foo == '?') {
hoz_echo(405, ifname);
return 405;
}
for (i = 0; *foo != '?'; foo++, i++, headersize++) {
if (i == 255) {
hoz_echo(405, ifname);
return 405;
}
aux[i] = *foo;
}
aux[i] = 0;
fullsize = (int) atol(aux);
if (!fullsize) {
hoz_echo(405, ifname);
return 405;
}
if (strncmp(foo, "?????", 5)) {
hoz_echo(405, ifname);
return 405;
}
foo += 5;
headersize += 5;
if (*foo == '?') {
hoz_echo(405, ifname);
return 405;
}
for (i = 0; *foo != '?'; foo++, i++, headersize++) {
if (i == 255) {
hoz_echo(405, ifname);
return 405;
}
aux[i] = *foo;
}
aux[i] = 0;
partsize = (int) atol(aux);
if (!partsize) {
hoz_echo(405, ifname);
return 405;
}
if (strncmp(foo, "?????", 5)) {
hoz_echo(405, ifname);
return 405;
}
foo += 5;
headersize += 5;
fclose(f);
return 0;
}
/**
* fsize - Retrieves the size of a file
* @path: filename
*/
size_t fsize(const char *path)
{
struct stat stats;
stat(path, &stats);
return (size_t) stats.st_size;
}
/**
* isfile - a file exists?
* @path: path to file
*/
int isfile(const char *path)
{
struct stat stats;
return (!stat(path, &stats) && S_ISREG(stats.st_mode));
}
/**
* isdir - a directory exists?
* @path: path to dir
*/
int isdir(const char *path)
{
struct stat stats;
return (!stat(path, &stats) && S_ISDIR(stats.st_mode));
}
/**
* hoz_nopath - returns a file name, without the path
* @file: the full filename
*/
char *hoz_nopath(const char *file)
{
char *aux;
aux = (char *) (file + strlen(file));
while (*aux != HOZ_PATHSEP) {
if (aux == file) {
return aux;
}
aux--;
}
return aux + 1;
}
/**
* mergepath - returns a file name, without the path
* @dir: the full diectory
* @fname: the full filename
* @out: the output
*/
int mergepath(const char *dir, const char *fname, char *out)
{
const char *dirp;
dirp = dir;
if (!fname || !*fname) {
return -1;
}
if (strcmp(dir, ".")) {
while (*dirp) {
*out++ = *dirp++;
}
if (dirp > dir && *(dirp - 1) != HOZ_PATHSEP) {
*out++ = HOZ_PATHSEP;
}
}
while (*fname) {
*out++ = *fname++;
}
*out = '\0';
return 0;
}
/*
* atolp(string)
* returns a _positive_ number extracted from the string
* if the string wasn't a number a 0 will be returned
*/
int atolp(const char *s)
{
int n = 0;
char *c = (char*)s;
while (*c) {
if (*c >= '0' && *c <= '9') {
n *= 10;
n += (*c++ - '0');
} else {
return 0;
}
}
return n;
}
/*
* atolmp(string, multiplier)
* returns a _positive_ number extracted from the string and multiplies it
* always returns an integer, 0 if the string wasn't a number
*/
int atolmp(const char *s, const int mult)
{
size_t n = 0, p = 0, d = 1;
char *c = (char*)s;
while (*c) {
if (*c == '.') {
if (p) {
return 0; /* more than one '.' in the string? error */
}
p = 1;
*c++;
} else if (*c >= '0' && *c <= '9') {
if (p) {
d *= 10; /* final decimal division */
}
n *= 10;
n += (*c++ - '0');
} else {
return 0;
}
}
if (d) {
n /= d;
}
n *= (size_t)mult;
if (n < 0) {
printf("DA FOC!\n");
/* number is too big for size_t, error */
return 0;
}
return n;
}
syntax highlighted by Code2HTML, v. 0.9.1