Versió inicial
Versió inicial de l'script. Actualització del README. Incorporació de l'especificació DESCRIPT.ION.
This commit is contained in:
parent
8d14696574
commit
e3dd305fa9
71
README.md
71
README.md
|
@ -1,4 +1,71 @@
|
||||||
# ook
|
# ook
|
||||||
|
|
||||||
Bash-script per generar un fitxer 'descript.ion' a partir de la descripció 'FILE_ID.DIZ' d'un fitxer 'ZIP'.
|
## Situació
|
||||||
Funciona per a un fitxer 'ZIP' concret, o pels 'ZIP' dins un camí recursiu.
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
`<EOF>`
|
||||||
|
|
|
@ -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[*<ID>Other program info]...<CR><LF>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
<ID> 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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue