diff --git a/NEWS b/NEWS index 4d6e80c..67ccdda 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,29 @@ Petit utilitaire qui permet de mettre a jour un fichier contenant une image ISO. Evolution des versions : +10/02/23 - Version 0.4 : +======================== + * Validation de la modification des donnees. + * Modification des options. + * La commande -p (--put) fonctionne. + Mais cela reste une version de test. + + Exemple : +$ isoupd -p debian-live-11.6.0-amd64-gnome.iso -f boot/grub/grub.cfg -h grub.phf +Taille du fichier sur l'ISO : 14757 +Taille du fichier local : 2533 +ATTENTION: La mise en place de ce fichier + va retrecir l'espace d'allocation disponible ! + (il sera de 4096 octets) +Les tailles sont differentes mais compatibles. +AVERTISSEMENT : Version 0.4 de test !!! +============= Il faut faire une sauvegarde de l'ISO avant. +Modification ? [o/N] +o +Ecriture de 2533 octets sur le secteur 2955 +Ecriture d'un nouveau repertoire sur 22 +OK ! + 08/02/23 - Version 0.2 : ======================== * Validation de l'acces aux donnees. diff --git a/src/Makefile b/src/Makefile index a8dba01..1c06f58 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ # Makefile pour Linux isoupd : isoupd.c - cc -o isoupd isoupd.c + cc -Wall -o isoupd isoupd.c clean : rm -f isoupd diff --git a/src/isoupd.c b/src/isoupd.c index ba05de0..87b6709 100644 --- a/src/isoupd.c +++ b/src/isoupd.c @@ -23,7 +23,7 @@ along with this program. If not, see #include #include -#define VERSION "0.2" +#define VERSION "0.4" typedef uint32_t loc_t; typedef uint8_t byte; #define CD_SECTOR_SIZE 0x800 /* 2048 */ @@ -38,9 +38,9 @@ typedef uint8_t bool; #define ALIGN(x,y) (((x) + ((y)-1)) & (~((y)-1))) static char *isofilename, *targetfilename, *targetdirname, *hostfilename; -static bool length_override = false; +static bool ecrase = false; -struct iso_directory_t { +struct iso_rep_t { uint8_t len; uint8_t ex_len; uint32_t lba; @@ -56,7 +56,7 @@ struct iso_directory_t { uint8_t fileid_len; char fileid[0]; } __attribute__((packed)); -typedef struct iso_directory_t iso_directory_t; +typedef struct iso_rep_t iso_rep_t; int getfilesize(FILE *f) { int spos = ftell(f); @@ -65,8 +65,8 @@ int getfilesize(FILE *f) { fseek(f, spos, SEEK_SET); return len; } -static int verbose_flag; -static int mode_flag=-2; /* 0=list, 1=put, -1=get */ +static int Verbose; +static int Mode=-2; /* 0=list, 1=put, -1=get */ void CdSetloc(FILE *f, loc_t newpos) { fseeko(f, newpos * CD_SECTOR_SIZE, SEEK_SET); @@ -81,10 +81,7 @@ void CdWrite(void *buf, loc_t nsectors, FILE *f) { } bool ispvd(byte *sec) { - return( - (sec[0] == 1) && - (memcmp(sec+1, "CD001", 5) == 0) - ); + return( (sec[0] == 1) && (memcmp(sec+1, "CD001", 5) == 0)); } bool streq(const char *s1, const char *s2) { @@ -93,84 +90,73 @@ bool streq(const char *s1, const char *s2) { bool scmplen(const char *s1, const char *s2, int len) { for(int i = 0; i < len; i += 1) { - if(tolower(s1[i]) != tolower(s2[i])) { - return false; - } + if(tolower(s1[i]) != tolower(s2[i])) return false; } return true; } -loc_t CdTell(FILE *isofile) { - loc_t s = ftell(isofile); +loc_t CdTell(FILE *fdi) { + loc_t s = ftell(fdi); return (s & (~(0x7FF))) / 0x800; } -bool CdFindFileInDir(iso_directory_t *out_dir, FILE* isofile, const char *filename, int filename_len, loc_t *out_secnum, loc_t *out_offset) { +bool CdFindFileInDir(iso_rep_t *out_dir, FILE* fdi, const char *filename, int filename_len, loc_t *out_secnum, loc_t *out_offset) { byte sec[CD_SECTOR_SIZE]; - iso_directory_t *dir = (iso_directory_t*)(sec); + iso_rep_t *dir = (iso_rep_t*)(sec); int slen = filename_len; int dirp = 0; - CdRead(sec, 1, isofile); + CdRead(sec, 1, fdi); - if (verbose_flag) printf("FFID %s %d\n", filename, slen); - + if (Verbose) printf("FFID %s %d\n", filename, slen); + while(dir->len != 0) { int dlen = dir->fileid_len; - if(!(dir->file_flags & 2)) { - dlen -= 2; - } - if ((mode_flag == 0) && ((strcmp(filename,"*")==0)||(strcmp(filename,"/*")==0))) { + if(!(dir->file_flags & 2)) dlen -= 2; + if ((Mode == 0)&&((strcmp(filename,"*")==0)||(strcmp(filename,"/*")==0))){ if (dlen>0) { dir->fileid[dlen] = '\0'; if ((dlen==1) && (dir->fileid[0] <= ' ')) { - if (verbose_flag) printf(" + 0x%x %d\n",(int)dir->fileid[0], dlen); + if (Verbose) printf(" + 0x%x %d\n",(int)dir->fileid[0], dlen); } else printf(" - %s %d\n",dir->fileid, dlen); } } else { if(dlen == slen) { - if (verbose_flag) printf(" + %s\n",dir->fileid); + if (Verbose) printf(" + %s\n",dir->fileid); if(scmplen(dir->fileid, filename, slen)) { - *out_dir = *dir; - if(NULL != out_secnum) { - *out_secnum = CdTell(isofile) - 1; - } - if(NULL != out_offset) { - *out_offset = dirp; - } - return true; + *out_dir = *dir; + if(out_secnum != NULL) *out_secnum = CdTell(fdi) - 1; + if(out_offset != NULL) *out_offset = dirp; + return true; } } } dirp += dir->len; if(dirp >= 0x800) { - CdRead(sec, 1, isofile); + CdRead(sec, 1, fdi); dirp = dirp % 0x800; } - dir = (iso_directory_t*)(sec + dirp); + dir = (iso_rep_t*)(sec + dirp); } return false; } -bool CdFindFile(iso_directory_t *outdir, FILE *isofile, const char *filename, loc_t *out_secnum, loc_t *out_offset) +bool CdFindFile(iso_rep_t *outdir, FILE *fdi, const char *filename, loc_t *out_secnum, loc_t *out_offset) { const char *next; const char *cur = filename; int slen; - if (verbose_flag) printf("> %s\n",filename); + if (Verbose) printf("> %s\n",filename); do { next = strchr(cur, '/'); - if(next == NULL) { - slen = strlen(cur); - } else { - slen = (int)(next - cur); - } - if(!CdFindFileInDir(outdir, isofile, cur, slen, out_secnum, out_offset)) - return false; - if(next != NULL) { - CdSetloc(isofile, outdir->lba); - next++; cur = next; - } else break; + if(next == NULL) slen = strlen(cur); + else slen = (int)(next - cur); + if (!CdFindFileInDir(outdir, fdi, cur, slen, out_secnum, out_offset)) + return false; + if (next != NULL) { + CdSetloc(fdi, outdir->lba); + next++; cur = next; + } else break; } while(next != NULL); return true; } @@ -178,7 +164,7 @@ bool CdFindFile(iso_directory_t *outdir, FILE *isofile, const char *filename, lo /* options definitions */ static int help_flag; static struct option long_options[] = { - {"verbose", no_argument, &verbose_flag, 1}, + {"verbose", no_argument, &Verbose, 1}, {"help", no_argument, &help_flag, 1}, {"list", no_argument, 0, 'l'}, {"put", no_argument, 0, 'p'}, @@ -191,7 +177,7 @@ static struct option long_options[] = { void explain(void) { - puts("Utilisation : isoupd [options] isofile"); + puts("Utilisation : isoupd [options] fichier.iso"); puts(" -l, --list liste d'un repertoire (defaut)"); puts(" -p, --put modifie un fichier de l'iso"); puts(" -g, --get extrait un fichier de l'iso"); @@ -199,7 +185,7 @@ void explain(void) puts(" -f, --file chemin du fichier dans l'iso"); puts(" -h, --host nom du fichier host. Obligatoire pour -p et -g"); puts(" -d, --dir nom du repertoire a lister dans l'iso"); - puts(" --help cette aide !"); + puts(" --help affiche cette aide !"); } void messerr(char * m, int err) { @@ -219,11 +205,11 @@ void errmode(char * o) int main(int N, char *P[]) { int c, l, opt_ind = 0; -FILE *hostfile, *isofile; +FILE *fdh, *fdi; char etoile[2] = "*"; - if(sizeof(iso_directory_t) != 33) { - fprintf(stderr, "Mauvaise compilation : tid=%lu\n",sizeof(iso_directory_t)); + if(sizeof(iso_rep_t) != 33) { + fprintf(stderr, "Mauvaise compilation : tid=%lu\n",sizeof(iso_rep_t)); return 9; } while (1) { @@ -237,19 +223,19 @@ char etoile[2] = "*"; break; case 'l': - if (mode_flag != -2) errmode(P[opt_ind]); - mode_flag=0; + if (Mode != -2) errmode(P[opt_ind]); + Mode=0; break; case 'p': - if (mode_flag != -2) errmode(P[opt_ind]); - mode_flag=1; + if (Mode != -2) errmode(P[opt_ind]); + Mode=1; break; case 'g': - if (mode_flag != -2) errmode(P[opt_ind]); - mode_flag=-1; + if (Mode != -2) errmode(P[opt_ind]); + Mode=-1; break; case 'v': - verbose_flag=1; + Verbose=1; break; case 'h': hostfilename = optarg; @@ -287,135 +273,133 @@ char etoile[2] = "*"; } /* verifications */ if (! isofilename) messerr("Fichier ISO absent",2); - if (mode_flag == -2) mode_flag = 0; /* defaut */ - switch(mode_flag) { + if (Mode == -2) Mode = 0; /* defaut */ + switch(Mode) { case 0 : /* list */ if (targetfilename) messerr("option -f inutile",2); if (hostfilename) messerr("option -h inutile",2); if (!targetdirname) targetdirname = etoile; - if (verbose_flag) printf("Liste de %s dans %s\n",targetdirname,isofilename); + if (Verbose) printf("Liste de %s dans %s\n",targetdirname,isofilename); targetfilename = targetdirname; break; case 1 : /* put */ if (targetdirname) messerr("option -d inutile",2); if (!targetfilename) messerr("Chemin du fichier dans l'ISO absent",2); if (!hostfilename) messerr("fichier host source absent",2); - if (verbose_flag) printf("PUT de %s vers %s dans %s\n",hostfilename,targetfilename,isofilename); + if (Verbose) printf("PUT de %s vers %s dans %s\n",hostfilename,targetfilename,isofilename); break; case -1 : /* get */ if (targetdirname) messerr("option -d inutile",2); if (!targetfilename) messerr("Chemin du fichier dans l'ISO absent",2); if (!hostfilename) messerr("fichier host destination absent",2); - if (verbose_flag) printf("GET de %s dans %s vers %s\n",targetfilename,isofilename,hostfilename); + if (Verbose) printf("GET de %s dans %s vers %s\n",targetfilename,isofilename,hostfilename); break; } - if (verbose_flag) printf("Verbose : mode = %d\n",mode_flag); + if (Verbose) printf("Verbose : mode = %d\n",Mode); - if ((isofile = fopen(isofilename, "r+")) == NULL) { + if ((fdi = fopen(isofilename, "r+")) == NULL) { fprintf(stderr, "Erreur ouverture ISO %s\n", isofilename); return 1; } if(hostfilename != NULL) { - if ((hostfile = fopen(hostfilename, "r")) == NULL) { - if (mode_flag == 1) { /* put */ + if ((fdh = fopen(hostfilename, "r")) == NULL) { + if (Mode == 1) { /* put */ fprintf(stderr, "Erreur ouverture fichier %s\n", hostfilename); return 1; } } else { - if (mode_flag == -1) { /* get */ + if (Mode == -1) { /* get */ fprintf(stderr,"Erreur : le fichier %s existe deja !\n",hostfilename); return 1; } } - if (mode_flag == -1) { /* get */ - if ((hostfile = fopen(hostfilename, "w")) == NULL) { + if (Mode == -1) { /* get */ + if ((fdh = fopen(hostfilename, "w")) == NULL) { fprintf(stderr, "Erreur creation fichier %s\n", hostfilename); return 1; } } } byte sec[CD_SECTOR_SIZE]; - iso_directory_t *dir = (iso_directory_t*)(sec); - CdSetloc(isofile, ISO_PADSIZE); - CdRead(sec, 1, isofile); + iso_rep_t *dir = (iso_rep_t*)(sec); + CdSetloc(fdi, ISO_PADSIZE); + CdRead(sec, 1, fdi); if(!ispvd(sec)) { fprintf(stderr, "%s n'est pas un fichier ISO\n", isofilename); return 1; } loc_t root_lba = *(loc_t*)(sec+158); - if (verbose_flag) printf("root lba = %x\n", root_lba); - CdSetloc(isofile, root_lba); + if (Verbose) printf("root lba = %x\n", root_lba); + CdSetloc(fdi, root_lba); loc_t dir_lba, dir_offset; - bool s = CdFindFile(dir, isofile, targetfilename, &dir_lba, &dir_offset); - if (!mode_flag) { /* list */ - fclose(isofile); + bool s = CdFindFile(dir, fdi, targetfilename, &dir_lba, &dir_offset); + if (!Mode) { /* list */ + fclose(fdi); return 0; } if(!s) { fprintf(stderr, "Fichier %s absent de l'ISO %s\n", targetfilename, isofilename); return 1; } - CdSetloc(isofile, dir_lba); - CdRead(sec, 1, isofile); - dir = (iso_directory_t*)(sec + dir_offset); + CdSetloc(fdi, dir_lba); + CdRead(sec, 1, fdi); + dir = (iso_rep_t*)(sec + dir_offset); int maxsize = ALIGN(dir->file_len, 0x800); printf("Taille du fichier sur l'ISO : %d\n", dir->file_len); - if (mode_flag == -1) { /* get */ + if (Mode == -1) { /* get */ byte *filedata = (byte*)(malloc(maxsize)); - CdSetloc(isofile, dir->lba); - CdRead(filedata, (maxsize / CD_SECTOR_SIZE), isofile); - fwrite(filedata, 1, dir->file_len, hostfile); - fclose(hostfile); - fclose(isofile); + CdSetloc(fdi, dir->lba); + CdRead(filedata, (maxsize / CD_SECTOR_SIZE), fdi); + fwrite(filedata, 1, dir->file_len, fdh); + fclose(fdh); + fclose(fdi); printf("Extraction faite dans %s.\n",hostfilename); return 0; } - int len = getfilesize(hostfile); + int len = getfilesize(fdh); int aligned_len = ALIGN(len, 0x800); printf("Taille du fichier local : %d\n", len); - printf("La commande --put n'est pas encore au point !\n"); - return 0; /* test */ - if(!length_override) { + if(!ecrase) { if(len > maxsize) { - fprintf(stderr, "Le fichier %s depasse de %d octets (%d > %d)\n", - hostfilename, - len - maxsize, - len, maxsize - ); - fclose(hostfile); - fclose(isofile); + fprintf(stderr, "Le fichier %s depasse de %d octets (%d > %d)\n", + hostfilename, len - maxsize, len, maxsize); + fclose(fdh); + fclose(fdi); return 1; } if((uint32_t)len != dir->file_len) { - if((uint32_t)aligned_len < dir->file_len) { - printf("ATTENTION: La mise en place de ce fichier va retrecir l'espace d'allocation disponible !\n"); - printf(" (il sera de %d octets)\n", aligned_len); - } - printf("Les tailles sont differentes mais compatibles. Modification ? [o/N]\n"); - int ch = getchar(); - if((ch != 'o') && (ch != 'O')) { - printf("Annulation !!\n"); - return 1; - } + if((uint32_t)aligned_len < dir->file_len) { + printf("ATTENTION: La mise en place de ce fichier\n va retrecir l'espace d'allocation disponible !\n"); + printf(" (il sera de %d octets)\n", aligned_len); + } + printf("Les tailles sont differentes mais compatibles.\n"); } } + printf("AVERTISSEMENT : Version %s de test !!!\n",VERSION); + printf("============= Il faut faire une sauvegarde de l'ISO avant.\n"); + printf("Modification ? [o/N]\n"); + int ch = getchar(); + if((ch != 'o') && (ch != 'O')) { + printf("Annulation !!\n"); + return 1; + } byte *filedata = (byte*)(malloc(aligned_len)); memset(filedata, 0, aligned_len); - fread(filedata, 1, len, hostfile); - fclose(hostfile); + fread(filedata, 1, len, fdh); + fclose(fdh); printf("Ecriture de %d octets sur le secteur %u\n", len, dir->lba); - CdSetloc(isofile, dir->lba); - CdWrite(filedata, (aligned_len / CD_SECTOR_SIZE), isofile); + CdSetloc(fdi, dir->lba); + CdWrite(filedata, (aligned_len / CD_SECTOR_SIZE), fdi); dir->file_len = len; printf("Ecriture d'un nouveau repertoire sur %u\n", dir_lba); - CdSetloc(isofile, dir_lba); - CdWrite(sec, 1, isofile); + CdSetloc(fdi, dir_lba); + CdWrite(sec, 1, fdi); printf("OK !\n"); - fclose(isofile); + fclose(fdi); return 0; }