#include <sys/stat.h>
#include <unistd.h>
#include "file_size.h"
-#include "filecopy.h"
-
-int exists(const char *fname)
-{
- struct stat buffer;
-
- if(stat(fname, &buffer) == 0)
- return 0;
- else
- return 1;
-}
void printHumanReadSize(const char *output, unsigned long long int splitgroesse)
{
splitgroesse, humanread, einheit);
}
-void splitter(const char *input, char *output, const char *rest,
- unsigned long long splitgroesse)
-{
- FILE *in;
- FILE *out;
- FILE *re;
- in = fopen(input, "r");
- out = fopen(output, "w");
-
- char pfad[255];
- unsigned long long filesize;
- struct stat st;
-
- while(fscanf(in, "%[^\n]\n", pfad) == 1) {
- stat(pfad, &st);
-
- // filesize inklusive overhead
- filesize = 33 + strlen(pfad) + st.st_size;
-
- if(splitgroesse >= filesize) {
- splitgroesse -= filesize;
- fprintf(out, "%s\n", pfad);
- } else {
- if(exists(rest) == 1)
- re = fopen(rest, "w");
-
- fprintf(re, "%s\n", pfad);
- }
- }
-
- fclose(in);
- fclose(out);
-
- if(exists(rest) == 0)
- fclose(re);
-
- printHumanReadSize(output, splitgroesse);
-}
int cmpfunc(const void *filea, const void *fileb)
{
return -2;
}
-void filesize_sort(const char *input, const char *output,
- const long long unsigned int split)
+int get_array_length(FILE *in)
{
- // in: input Textdatei; out: output Textdatei;
- // ignore: output Textdatei; zugrosse Dateien
- FILE *in;
- FILE *out;
- FILE *ignore;
- char pfad[255];
- struct stat st;
int lines = 0;
+ char pfad[255];
- in = fopen(input, "r");
- out = fopen(output, "w");
-
- // input-Datei Zeilenanzahl
while(fscanf(in, "%[^\n]\n", pfad) == 1) {
lines++;
}
- fseek(in, 0L, SEEK_SET);
+ rewind(in);
+ lines--;
- // struct Array with Dateienanzahl
- struct file_size fs[lines -1];
- lines = 0;
+ return lines;
+}
+
+unsigned long fill_array_from_file(FILE *in, struct file_size *fs,
+ const long long unsigned int split)
+{
+ FILE *ignore;
+ char pfad[255];
+ struct stat st;
+ int lines = 0;
while(fscanf(in, "%[^\n]\n", pfad) == 1) {
// Lese Dateieigenschaften in st struct
// kopiert den pfad String ins struct
strcpy(fs[lines].name, pfad);
// Filesize in struct
- fs[lines].fsize = st.st_size;
- lines++;
+ fs[lines++].fsize = st.st_size;
} else {
// irgnore List erstellen
- if(exists("ignore") == 1)
+ if(ignore == NULL)
ignore = fopen("ignore", "w");
fprintf(ignore, "%s\n", pfad);
}
}
- // sortiere das array fs mit stucts
- qsort(fs, lines, sizeof(struct file_size), cmpfunc);
+ fs = (struct file_size *)realloc(fs, lines * sizeof(struct file_size));
- // schreibe in out die sortieren liste
- for(int i = 0; i < lines; i++) {
- fprintf(out, "%s\n", fs[i].name);
- }
-
- // schliesse alle Textdateien
- fclose(in);
- fclose(out);
- if(exists("ignore") == 0)
+ if(ignore != NULL)
fclose(ignore);
+
+ return lines;
}
void usage()
printf(" -f <Größe>\tOption zur Größenangabe in Bytes\n\n");
}
+int splitter(struct file_size *input, const char *output,
+ unsigned long long splitgroesse, int length)
+{
+ struct file_size *rest = (struct file_size *)malloc(length * sizeof(struct file_size));
+ int restcount = 0;
+ unsigned long long int filesize;
+ FILE *out;
+
+ out = fopen(output, "w");
+ for(int i = 0; i <= length; i++) {
+ // filesize inklusive overhead
+ filesize = 33 + strlen(input[i].name) + input[i].fsize;
+
+ if(splitgroesse >= filesize) {
+ if(i < length) {
+ splitgroesse -= filesize;
+ fprintf(out, "%s\n", input[i].name);
+ } else {
+ fprintf(out, "%s", input[i].name);
+ }
+ } else {
+ rest[restcount++] = input[i];
+ }
+ }
+ fclose(out);
+
+ printHumanReadSize(output, splitgroesse);
+
+ if(restcount > 0) {
+ memcpy(input, rest, length * sizeof(struct file_size));
+ input = (struct file_size *)realloc(input, restcount * sizeof(struct file_size));
+ }
+
+ free(rest);
+ // -1 weil vor Schleifenende nochmal incrementiert wird
+ return restcount - 1;
+}
+
int main(int argc, char *argv[])
{
- // input: Textdatei mit Quellpfaden
const char *input = argv[1];
- // output: gesplittete Textdatei mit Quellpfaden
const char *output = argv[2];
- // rest: temp restliche Datein,
- // die nicht aufs Medium passen
- const char *rest = "rest";
- // work: temp Datein,
- // die auf das Medium passen
- const char *work = "work";
// Medien groessen
const unsigned long long dvd9 = 8497902848;
}
}
- // schreibt eine soritere Liste in rest
- filesize_sort(input, rest, split);
+ // Liest die Quelldatei in den Ram
+ FILE *in = fopen(input, "r");
+ int s_length = get_array_length(in);
+ struct file_size *fs = (struct file_size *)malloc((s_length + 1) * sizeof(struct file_size));
+ s_length = fill_array_from_file(in, fs, split);
+ fclose(in);
+
+ // sortieren
+ qsort(fs, s_length, sizeof(struct file_size), cmpfunc);
- char outname[sizeof output] = "";
+ char outname[strlen(output) + 3];
int num = 1;
- while(exists(rest) == 0) {
+ while(s_length > 0) {
sprintf(outname, "%s%03d", output, num++);
- if(exists(rest) == 0) {
- filecopy(rest, work);
- remove(rest);
- }
- splitter(work, outname, rest, split);
+ s_length = splitter(fs, outname, split, s_length);
}
- remove(work);
-
+ free(fs);
return 0;
}