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.