diff --git a/README.md b/README.md index 20b251b..124444a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,71 @@ # ook -Bash-script per generar un fitxer 'descript.ion' a partir de la descripció 'FILE_ID.DIZ' d'un fitxer 'ZIP'. -Funciona per a un fitxer 'ZIP' concret, o pels 'ZIP' dins un camí recursiu. \ No newline at end of file +## Situació + +El programari `BBBS` implementa de manera nativa la gestió automàtica i desassistida de fitxers d'usuari quan aquests arriben per canals de distribució `TIC`(propis de *FidoNet*). Així, de manera transparent, el sistema: +- Importa els nous fitxers. +- Actualitza les noves versions dels fitxers existents. +- Distribueix als diferents links els respectius fitxers d'acord amb les seves respectives configuracions. + +EL programari `BBBS` també contempla la gestió anterior de manera manual i assistida, a través dels menús propis del sistema en connexió local o telnet. + + +### Problema + +El programari `BBBS` no contempla l'addició, ni manual ni automàtica, de nous fitxers si aquests no s'incorporen al sistema mitjançant els dos mètodes anteriors. + +Imaginem alguns casos d'ús d'incorporacions: + +- Col·leccions de fitxers (p. ex. una sèrie de capítols d'un còmic, a fitxer per capítol) +- Fitxers serialitzats (p. ex. un fitxer de gran mida comprimit en volums, a fitxer per volum) +- Conjunt de fitxers independents en una carpeta comuna (p. ex. les fotografies diàries que fa la NASA, a fitxer per foto) + +En aquests casos, per a posar a disposició dels meus usuaris aquests fitxers, hauria d'optar entre aquestes dues opcions: + +- Crear manualment un fitxer `.TIC` per a cada nou fitxer i importar-lo al sistema (això semi-automatitzaria bellugar el fitxer de la carpeta `inbound` a la destinació predefinida per l'àrea `TIC`, i actualitzaria l'índex en el seu respectiu fitxer `descript.ion`[^1]). +- Bellugar el fitxer a l'ubicació apropiada i actualitzar el fitxer `descript.ion` que fa d'índex de fitxers en cada una de les carpetes de la base de fitxers del `BBS`. + +En tots dos casos, l'esforç és molt superior al benefici i, en el meu cas, justifica que tingui *terabytes* d'informació pendents d'incorporar a `EOTB`. + + +## Solució + +He desenvolupat `ook.sh`, un *script* en `bash` que ha de donar resposta a aquesta necessitat, com a eina de suport a un `SysOp` de `BBBS`. + +`ook.sh` genera i/o manté els fitxers `descript.ion` a partir de la descripció `FILE_ID.DIZ` dels fitxers `ZIP` que se l'hi indiquen, en una ubicació estàtica o recursiva. + + +### Requisits + +`ook.sh` necessita que les utilitats `unzip`, `grep`, `file` i `stat` estiguin disponibles en el sistema per tal de poder efectuar les operacions necessàries. + +Tanmateix, aquest *script* s'ha provat en un `shell` `bash` compatible, de manera que si fas servir un altre `shell` pot ser necessari ajustar-lo en corcondànça. Això podria aplicar-se a `Windows WSL` fent possible executar aquest *script* en una instal·lació de `BBBS` sobre `MS Windows`. + + +### Funcionalitat: + +- **Magic Number**: Utilitzo la comanda `file` per a assegurar que un arxiu processable sigui realment un ZIP[^2], verificant si la sortida de la comanda conté `'Zip archive data'`. + +- **Processament de ZIP**: Per a cada arxiu `ZIP`, l'*script* verifica si ja està registrat en el seu `descript.ion`. Si ho està, omet el seu processat. En cas de no estar-ho, extreu[^3] el contingut del fitxer `file_id.diz` (*case-insensitive*) i l'incorpora en el `descript.ion`, en la mateixa línia que el nom de l'arxiu `ZIP`, substituint els salts de línia amb `@n` (codificació que `BBBS` interpreta com a salt de línia). + +- **Recursivitat**: Si s'especifica el paràmetre `-r`, l'*script* processa de manera recursiva tots els subdirectoris. Si no, només processa el directori actual. + +- **Processar un ZIP específic**: Si s'especifica el paràmetre `-s` seguit del nom d'un arxiu `ZIP`, només es processa aquest arxiu. + +- **Resum**: En finalitzar la seva execució, el *script* mostra un resum amb el nombre total de nous arxius `ZIP` processats i la mida total en bytes d'aquests arxius. + + +### Execució: + +En el `path` on s'executa: + +- **Mode directori recursiu**: `./script.sh -r` +- **Mode ZIP específic**: `./script.sh -s arxiu.zip` +- **Mode directori actual (sense recursivitat)**: `./script.sh` + +[^1]: A títol informatiu en el repositori incloc l'especificació original del format `DESCRIPT.ION` de `JP Software Inc.`. +[^2]: No contemplo el fet d'incorporar altres dels compressors suportats per `BBBS` perquè `ZIP` és el meu estàndard. +[^3]: No contemplo el processat de fitxers `ZIP` protegits amb paraula de pas perquè `BBBS` ja gestiona la seguretat d'accés granular als continguts. + + +`` diff --git a/description.txt b/description.txt new file mode 100644 index 0000000..83fd942 --- /dev/null +++ b/description.txt @@ -0,0 +1,65 @@ + JP Software Inc. + P.O. Box 328 + Chestertown, MD 21620, USA + + 410-810-8818 + fax 410-810-0026 + Email sales@jpsoft.com + Web http://www.jpsoft.com/ + +Technical Note -- Using DESCRIPT.ION +------------------------------------ + +4NT and Take Command use the file DESCRIPT.ION to store file descriptions. +This file is created as a hidden file in each subdirectory which has +descriptions, and deleted when all descriptions are removed or when all +files with descriptions are deleted. If you remove the hidden attribute +from the file, it will not be hidden again. + +Your programs can access DESCRIPT.ION to create, retrieve, or modify +file descriptions, and to store other information. DESCRIPT.ION has one +line per file, and is unsorted. Each line is in the following format: + + filename.ext Description[*Other program info]... + +There is normally one space between the description and filename but +additional spaces may be used in future versions. The characters +after the description allow extension of the description format +for use by other programs. They are as follows: + + * is an ASCII Ctrl-D (04), and marks the end of the description + text and the beginning of information for a program other than + 4NT or Take Command. This symbol can appear multiple times on each + line; each occurrence marks the beginning of information for another + program. + + is an identification byte for the program which is using this + area of the particular line. If you are writing a program which + will store information in DESCRIPT.ION, test it using an ID byte of + your own choosing. When you are ready to release the program, + contact JP Software and we will provide you with an ID byte value + that is not in use by others to the best of our knowledge. + + Other program info is any text the program wishes to store in its + area of the line. The text should relate specifically to the file + named on the line. It may not contain the Ctrl-D character, + carriage returns, line feeds, or nulls (ASCII 0s). + +4NT and Take Command will copy, delete, or move all the information on a +line in DESCRIPT.ION, including information owned by other programs, when +performing the same action on the corresponding file. They will also +change the name if a file is renamed. To support DESCRIPT.ION properly, +your program must do the same if it copies, deletes, moves, or renames +files. Take care not to remove information which does not belong to +your program, or delete lines which contain information for other +programs. Your program should be able to handle a line terminated by a +CR or LF alone, a CR/LF pair, an EOF (ASCII 26), or the physical end of +the file. The lines it creates should be terminated with CR / LF. The +line length limit is 4096 bytes; exceeding this limit will cause +unpredictable results. + +======================================================================= +JP Software Inc. P.O. Box 328, Chestertown, MD 21620, USA +phone: 410-810-8818 fax: 410-810-0026 +WWW: http://jpsoft.com email: sales@jpsoft.com + diff --git a/ook.sh b/ook.sh new file mode 100755 index 0000000..ed27b94 --- /dev/null +++ b/ook.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +# Variables pel resum +total_zips=0 +total_size=0 + +# Funció per a processar arxius ZIP en un directori +processar_zip() { + zip_file="$1" + dir="$2" + index_file="$dir/descript.ion" + + # Verificar si és un arxiu ZIP per magic number + if file "$zip_file" | grep -q 'Zip archive data'; then + # Obtenir el nom de l'arxiu ZIP sense la ruta + zip_name=$(basename "$zip_file") + + # Verificar si ja ha estat registrat a descript.ion + if grep -q "^$zip_name " "$index_file" 2>/dev/null; then + echo "Arxiu ZIP '$zip_name' ja registrat a '$index_file'." + else + # Buscar i extreure el contingut de qualsevol arxiu que coincideixi amb FILE_ID.DIZ (case-insensitive) + file_id_content=$(unzip -Z1 "$zip_file" | grep -i 'file_id.diz' | while read -r diz_file; do + unzip -p "$zip_file" "$diz_file" 2>/dev/null | tr -d '\r' | tr '\n' '@n' + done) + + # Si s'ha trobat i extret l'arxiu file_id.diz + if [ -n "$file_id_content" ]; then + echo "$zip_name $file_id_content" >> "$index_file" + echo "Arxiu ZIP '$zip_name' processat i registrat a '$index_file'." + + # Actualitzar resum + total_zips=$((total_zips + 1)) + total_size=$((total_size + $(stat -c%s "$zip_file"))) + else + echo "No s'ha trobat 'file_id.diz' a '$zip_name'." + fi + fi + else + echo "'$zip_file' no és un arxiu ZIP vàlid." + fi +} + +# Funció per a processar un directori +processar_directori() { + dir="$1" + recursive="$2" + + # Crear descript.ion si no existeix + index_file="$dir/descript.ion" + if [ ! -f "$index_file" ]; then + touch "$index_file" + echo "Arxiu 'descript.ion' creat a '$dir'." + fi + + # Buscar arxius ZIP en el directori + for zip_file in "$dir"/*.zip "$dir"/*.ZIP "$dir"/*.Zip "$dir"/*.ZiP; do + [ -e "$zip_file" ] && processar_zip "$zip_file" "$dir" + done + + # Processar subdirectoris si s'indica recursivitat + if [ "$recursive" = true ]; then + for subdir in "$dir"/*/; do + [ -d "$subdir" ] && processar_directori "$subdir" true + done + fi +} + +# Processar un arxiu ZIP específic +processar_unic_zip() { + zip_file="$1" + dir=$(dirname "$zip_file") + processar_directori "$dir" false +} + +# Verificar paràmetres +if [ "$1" = "-r" ]; then + # Mode recursiu + processar_directori "." true +elif [ "$1" = "-s" ] && [ -n "$2" ]; then + # Modo d'arxiu ZIP únic + if [ -f "$2" ]; then + processar_unic_zip "$2" + else + echo "L'arxiu específic no existeix." + fi +else + # Mode normal (no recursiu) + processar_directori "." false +fi + +# Mostrar resum +echo "Total d'arxius ZIP nous processats: $total_zips" +echo "Mida total dels arxius ZIP processats: $total_size bytes" +