Mai 192011
#include <stdio.h> #include <assert.h> #include <string.h> #include <stdbool.h> #include <unistd.h> #include <ctype.h> const char * strtera="To"; const char * strgiga="Go"; const char * strmega="Mo"; const char * strkilo="Ko"; const char * stroctets="octets"; const char * strunkwn="inconnu"; #define TERA 1099511627776 #define GIGA 1073741824 #define MEGA 1048576 #define KILO 1024 const long tera = TERA; const long giga = GIGA; const long mega = MEGA; const long kilo = KILO; long unit=0; char buffer[4096]; unsigned long size=0; const char * filename = NULL; int justdoit = false; const char* strofunit(const long u) { switch (u) { case TERA : return strtera; case GIGA : return strgiga; case MEGA : return strgiga; case KILO : return strkilo; case 1 : return stroctets; default : return strunkwn; } } void usage(void) { fprintf(stderr, "\n"); fprintf(stderr, "usage : zerogen -f filename -s size \n"); fprintf(stderr, " size peut tre specit avec une unit comme '12G' or '125M' \n"); fprintf(stderr, " Si l'unit n'est pas spcifie avec size, elle peut l'etre avec -u (mais pas les deux)\n"); fprintf(stderr, " En l'absence de toute unit, la taille est considre tre en octets.\n"); fprintf(stderr, " La taille ne doit en aucun cas depasser 8To (comportement imprvisible dans ce cas).\n"); fprintf(stderr, " \n"); fprintf(stderr, " zerogen ne modifiera pas les fichiers qui existent dja\n"); fprintf(stderr, " \n"); fprintf(stderr, " exemple : \n"); fprintf(stderr, " zerogen -f disk.img -s 20G\n"); fprintf(stderr, " zerogen -f disk2.img -s 20 -u G\n"); fprintf(stderr, " \n"); } int getarg(int argc, char* argv[] ) { int c; int tmp; char tmp2; if (!argc) return false; while ( (c = getopt(argc, argv, "jS:s:u:f:")) != EOF ) { switch(c) { case 'j' : justdoit=true; break; case 's' : case 'S' : if (size) { printf("Erreur : la taille est specifie plusieurs fois\n"); return false; } tmp = sscanf(optarg,"%lu%c", &size, &tmp2); if ( ! tmp ) return false; if ( tmp == 2 ) switch ( toupper(tmp2) ) { case 'T' : unit = tera; break; case 'G' : unit = giga; break; case 'M' : unit = mega; break; case 'K' : unit = kilo; break; case 'O' : unit = 1; break; } break; case 'u' : if (unit) { printf("Erreur : Conflit d'units\n"); return false; } switch ( toupper(optarg[0]) ) { case 'T' : unit = tera; break; case 'G' : unit = giga; break; case 'M' : unit = mega; break; case 'K' : unit = kilo; break; case 'O' : unit = 1; break; } break; case 'f' : filename = optarg; break; case '?' : perror("Option inconnue\n"); return false; } } if ( !filename ) { fprintf(stderr,"fichier non specifie : utilisez l'option -f \"fichier\"\n"); return false; } if ( ! size ) { fprintf(stderr, "taille non spcifie : utiliser l'option -s taille \n"); return false; } if ( !unit ) { fprintf(stderr,"unit non specifie : On considere que la taille specifiee est en octets\n"); unit=1; } if ( !unit ) { fprintf(stderr,"unit non specifie : utilisez l'option -uO -uK -uM -uG -uT pour specifier octets, kilo, mega, giga\n"); return false; } return true; } int main (int argc, char* argv[]) { FILE* f; int w; assert( sizeof(long) == 8 ); assert( sizeof(size_t) == 8); memset(buffer, 0, 4096); if ( ! getarg(argc, argv) ) { usage(); return 1; } f = fopen(filename, "r"); if (f && !justdoit) { fclose(f); fprintf(stderr,"Le fichier existe dj specifiez -j pour passer outre (-j comme just do it)\n"); return 1; } if (f && !justdoit) fclose(f); printf("Cration du fichier [%s] de taille %lu %s\n", filename, size, strofunit(unit)); f = fopen(filename, "w"); assert(f); fseek(f, (size*unit)-1 , SEEK_SET); w=fwrite(buffer, 1, 1, f); assert(w); fclose (f); return 0; }
Sorry, the comment form is closed at this time.