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
|
||||
|
||||
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.
|
||||
## 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.
|
||||
|
||||
|
||||
`<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