Una especie de joiner en C para Linux
bueno, lo hice para linux 
el codigo y los archivos binarios estan aca:
http://www.badongo.com/file/10771735
el codigo tiene muchos comentarios, creo que no hace falta aclarar mucho, solo unas cosas
es por consola, nada de lindas ventanitas, se le pasnas los archivos por argumentos
tiene que estar copilado el unjoiner.c con el nombre “unjoiner” (sin extencion ni nada)
y el formato del archivo “salida” (que se va a llamar “out”) es asi:
[
unjoiner
]
***
[4bytes pra tamaño del proximo archivo]
[nombre del archivo terminado en un caracter 0]
[archivo]
[4bytes pra tamaño del proximo archivo]
[nombre del archivo terminado en un caracter 0]
[archivo]
[4bytes pra tamaño del proximo archivo]
[nombre del archivo terminado en un caracter 0]
[archivo]
[... osea, eso repetido dependiendo de los archivos xD]
[4bytes para el tamaño de todos los archivos agregados, osea, el tamaño desde los *** hasta el ultimo byte del ultimo archivo]
[1byte para indicar si se ejecuta el archivo nº 1 pasado en los argumentos, 0 para que no y 1 para que si]
ahora los codigos
joiner:
/*joiner 01 julio 2008 by Ni0 ni0@el-hacker.org*/ /* 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 3 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, see . */ /*a este codigo le falta el unjoiner, se compilan por separado pero se necesitan los 2 ejecutables, y tienen que estar en la misma carpeta el unjoiner tiene que estar con el nombre "unjoiner" SI o Si (exepto que cambien este codigo xD)*/ #include stdio.h /*ponganle los simbolos de mayor y menor... o sino descargan el archivo y listo xD*/ #include string.h #include sys/stat.h #include unistd.h void usage(char *argv)/* te indica como se usa el programa*/ { printf("\n\tERROR:Mal Argumentos\n%s [-n] archivo1 archivo2 archivo3 ...\n\nel programa agrega los archivos especificados como argumento en el archivo \"unjoiner\"(que es una copia de program, NO ELIMINAR NI CAMBIAR DE NOMBRE) del cual despues de usar el joiner va a salir un archivo \"out\" al cual SI se le puede cambiar el nombre, al ejecutar el arhivo \"out\" (o el nuevo nombre que le hayan puesto) va a extraer los archivos y va a ejecutar el \"archivo1\", exepto que se use el argumento -n que le indica que no ejecute nada\nlos archivos van a ser extraidos en la misma carpeta que indica el agumento, por lo que si se quiere que se extraigan en la misma carpeta que program, los archivos tienen que estar en la misma carpeta que joiner, ejemplos:\n\njoiner juego imagen.bmp sonido/misonido.mp3\n este va a poner los archivos indicados en \"out\" y este los va a extraer imagen.bmp en la misma carpeta, exepto misonido.mp3 que va a crear la carpeta sonido/ y ahi dentro pondra misonido.mp3\n", argv); } int main(int argc, char **argv) { FILE *f, *j;/*los archivos, f para el archivo indicado para unir y en j el programa que va a resultar de unir todo*/ int arg;/*que argumento estamos trabajando*/ unsigned long size = 0, sizef = 0;/*size para el tamaño TOTAL y en sizef el tamaño del archivo que estamos uniendo*/ unsigned char c; if(argc == 1 || (argv[1][0] == '-' && (argv[1][1] != 'n' || argv[1][2] != 0))){/* si estan mal puestos los argumentos...*/ usage(argv[0]); return 1; } f = fopen("unjoiner", "rb"); if(f == NULL){ printf("\n\tERROR: no se encuentra el archivo program\nno se encontro el archivo program, re compilelo con el nombre \"unjoiner\" .\n"); return 1; } j = fopen("out", "wb"); if(j == NULL){ printf("\n\tERROR: no se pudo abrir el archivo \"out\" como escritura\nasegurese que tiene permiso para abrir ese archivo o que no esta siendo utilizado por otro programa\n"); return 1; } arg = fgetc(f);/*uso arg simplente para no declarar otra variable*/ while(!feof(f)){ fputc(arg, j);/*copiamos todo el unjoiner de unjoiner a out*/ arg = fgetc(f); } fclose(f); arg = 1; if(argv[1][0] == '-')/*esto significa que se puso -n tonces se lo saltea*/ arg++; while(arg != argc){ if((f = fopen(argv[arg], "rb")) == NULL){/*si no pudo abrir el argumento...*/ printf("\n\tERROR:archivo no encontrado\nel archivo \"%s\" no existe (argumento numero %d)\n", argv[arg], arg); return 1; } while(!feof(f)){/*calcula el tamaño*/ fgetc(f); sizef++; size++; if(size == 0xFFFFFFFF){/*sino habria overflow xD y en el out quedaria cualquier cosa*/ printf("\n\tERROR: los archivos superan los %d bytes\n", 0xFFFFFFFF); return 1; } } sizef--;/*se lee un caracter de mas, el caracter EOF, por eso tengo que restarle 1*/ size--; if(strlen(argv[arg]) > 300){ printf("\n\tERROR:el nombre del archivo %s tiene mas de 300 caracteres\n", argv[arg]); return 1; } size += strlen(argv[arg]) + 5;/*al tamaño le tiene que sumar el nombre, un caracter 0 y 4 bytes para indicar el tamaño del archivo*/ fclose(f); fputc((unsigned char)sizef, j);/*escribimos el tamaño del archivo, pero de a bytes*/ fputc((unsigned char)(sizef / 0x100), j); fputc((unsigned char)(sizef / 0x10000), j); fputc((unsigned char)(sizef / 0x1000000), j); fprintf(j, "%s", argv[arg]);/*ponemos el nombre del archivo*/ fputc('', j);/*el caracter 0*/ /*lo que va a hacer el unjoiner es leer el tamaño del archivo, despues leer hasta encontrar el caracter 0 y despues leer la cantidad de bytes que dice el tamaño del archivo*/ f = fopen(argv[arg], "rb"); while(!feof(f)){/*y copiamos el archivo a out*/ c = fgetc(f); if(c == 0xFF) fputc(0, j); else fputc(c + 1, j); } fclose(f); sizef = 0; arg++;/*pasamos al siguiente argumento*/ fseek(j, -1, SEEK_CUR);/*como se lee un caracter de mas, tengo que volver para atras*/ } /*ponemos el tamaño de TODOS los archivos, de sus nombres y de su tamaño*/ fputc((unsigned char)size, j); fputc((unsigned char)(size / 0x100), j); fputc((unsigned char)(size / 0x10000), j); fputc((unsigned char)(size / 0x1000000), j); if(argv[1][0] == '-')/*y ponemos 0 si no hay que ejecutar el primer argumento, o sino 1*/ fputc((char)0x00, j); else fputc((char)0x01, j); fclose(j); chmod("out", ALLPERMS);/*le ponemos los permisos... (ALLPERMS xD)*/ return 0; }
unjoiner:
/*unjoiner 01 julio 2008 by Ni0 ni0@el-hacker.org*/ /* 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 3 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, see . */ /*a este codigo le falta el joiner, se compilan por separado pero se necesitan los 2 ejecutables, y tienen que estar en la misma carpeta el unjoiner tiene que estar con el nombre "unjoiner" SI o Si (exepto que cambien el codigo del joiner xD)*/ #include stdio.h /*ponganle los simbolos de mayor y menor... o sino descargan el archivo y listo xD*/ #include string.h #include stdlib.h #include sys/stat.h #include unistd.h int main(int argc, char **argv) { FILE *u, *f; unsigned long size = 0, n = 0, pos = 0, posf = 0;/*size para saber el tamaño total y de los archivos independientes, n para manejarse entre las cadenas, pos para saber la posicion en la que estamos del archivo y posf para saber la posicion final, hasta donde tenemos que llegar*/ char t[301], exe, exef[320], _exef[320], *barra, *barraa, cwd[320];/*t es el nombre del archivo que estamos trabajando exe es si se ejecuta o no el primer archivo, exef es el archivo a ejecutar (en caso de que exe sea 1), _exef es el comando que se va a usar con system para ejecutar el archivo, barra indica la barra '/' del nombre de un archivo, barraa indica la barra '/' anterior a "barra" xD y cwd es el CurrentWorkDirectory, para saber donde estamos trabajando*/ unsigned char c; u = fopen(argv[0], "rb");/*nos abrimos a nosotros mismos*/ if(u == NULL){ printf("\n\tERROR: no se pudo abrirse el archivo %s\n", argv[0]); return 1; } exef[0] = 0; fseek(u, -5, SEEK_END);/*volvemos 5 bytes para atras desde el final*/ fgetpos(u, &posf);/*obtenemos la posicion final*/ size += fgetc(u);/*byte 1*/ size += fgetc(u) * 0x100;/*byte 2*/ size += fgetc(u) * 0x10000;/*byte 3*/ size += fgetc(u) * 0x1000000;/*byte 4*/ /*fijense que se leyo de la misma forma que se escribio*/ exe = fgetc(u);/*byte 5, indica si se ejecuta o no*/ fseek(u, size * (-1) - 5, SEEK_END);/*tenemos que retroceder los 5 bytes de antes MAS el tamaño total de todo lo que agregamos, pero como es para ATRAS tiene que estar en negativo*/ getcwd(cwd, 320);/*obtenemos el directorio*/ while(posf != pos){ /*mientras que no estemos en la posicion final...(osea, se acabaron los archivos)*/ memset(t, 0, 301);/*pongo en 0 a t*/ barraa = barra = t - 1;/*ponemos que apunten a t - 1, ya van a ver*/ /*leemos el tamaño de un archivo*/ size = 0; size += fgetc(u); size += fgetc(u) * 0x100; size += fgetc(u) * 0x10000; size += fgetc(u) * 0x1000000; n = 0; while((t[n] = fgetc(u)) != 0)/*leemos el nombre hasta que haya un caracter 0*/ n++; if(exe == 1){/*si hay que ejecutar, copiamos t a exef y ponemos en 0 a exe para que no vuelva a hacer esto cuando venga el otro archivo xD*/ strcpy(exef, t); exe = 0; } while((barra = strchr(barra + 1, '/')) != NULL){/*tenemos que crear los directorios antes de crear el archivo, entonces buscamos las barras /, barra apuntaba a t - 1, barra + 1 apunta a t
*/ *barra = 0;/*ponemos en 0 la barra, para que parezca que solo tengamos el directorio*/ mkdir(barraa + 1, ALLPERMS);/*creamos el directorio con todos los permisos y nos ponemos ahi, por si hay sub direcotios dentro de este, barraa apuntaba a t - 1*/ chdir(barraa + 1); barraa = barra;/*ponemos donde estaba la barra anterior*/ /*cuando vuelva a ejecutar, barra + 1 indica donde estaba la barra + 1 poscision, sino apuntaria al 0, entonces ahora busca una barra en el resto del nombre si la encuentra crea el directorio usando barraa + 1, osea la barra anterio (ahora 0) mas una posicion para que no apunte al 0 esa es la razon por la que apuntan a t - 1*/ } chdir(cwd);/*volvemos a donde estabamos
*/ while(t[strlen(t) + 1] != 0)/*t[strlen(t)] apunta al caracter 0 final, strlen(t) - 1 apuntaria al ultimo caracter antes del 0, strlen(t) + 1 apunta al siguiente caracter despues del 0, si no es 0, es porque habia una '/'...*/ t[strlen(t)] = '/'; f = fopen(t, "wb"); if(f == NULL){ printf("\n\tERROR: no se pudo crear el archivo\n el archivo %s no se pudo crear\n", t); return 1; } while(size != 0){/*ponemos el archivo hasta que se acaben los bytes del tamaño*/ c = fgetc(u); if(c == 0) fputc(0xFF, f); else fputc(c - 1, f); size--; } fclose(f); chmod(t, ALLPERMS);/*al archivo le ponemos todos los permisos*/ fgetpos(u, &pos); } fclose(u); if(exef[0] != 0){ barra = barraa = exef - 1; while((barra = strchr(barra + 1, '/')) != NULL){/*hacemos lo mismo que antes para saber los subdirectorios pero no los creamos, sino que nos posicionamos*/ *barra = 0; chdir(barraa + 1); barraa = barra; } strcpy(_exef, "./\""); strcat(_exef, barraa + 1); strcat(_exef, "\""); system(_exef);/*y ejecutamos el archivo, barraa + 1 para que solo sea el nombre del archivo, sino apuntaria tambien a la ruta y yo quiero que se ejecute desde la carpeta en la que esta*/ } return 0; }
cualquier duda solo pregunten… o cualquier problema que tienen
salu2!