Newsgroup: it.comp.os.linux.development
Titolo: dischetti e file

Salve a tutti.
avrei una domanda: come faccio a sapere la dimensione di un dischetto, 
a parte leggere l'etichetta :), da C?
ho provato con fstat su /dev/fd0, ma mi da' 0.
ho provato kon fseek, e mi da' 2.
tra l'altro la copia con fread e fwrite mi riesce, quindi non sono 
problemi di permessi, e a me serve sapere a priori quanto e' grande, 
quindi scartiamo subito il conteggio dei byte letti :)

du -k
non so se va prima montato comunque
du -k ti da la dimensione in kilobyte
du -m in megabyte

"Panther" ha scritto:

ti ringrazio, ma non mi sembra adatto, per vari motivi:
1 - e' un comando console
2 - devo montare il dispositivo
3 - usando la directory di mount mi da' lo spazio occupato, a me serve 
sapere se la dimensione e' 360K, 1.2M, 2.8M etc etc



Putroppo in linux operazioni come stat e lseek su devices non funzionano
come ti aspetteresti. L'unico modo e'
1) leggere tutto il file fino alla fine e vedere quanti bytes hai letto.
   Questo metodo e' il piu' semplice ma e' anche il piu' lento. Molto
   lento nel caso di devices di grosse dimensioni...
2) lseek, anche se non ritorna un valore corretto comunque sposta il
   puntatore del file, quindi se fai lseek(floppy, 1440*1024, SEEK_SET),
   posizionandoti quindi di un byte oltre la fine del floppy di 1440Kb,
   una successiva read(floppy, buf, 1) ritornerebbe 0 e quindi sapresti
   che sei che sei andato troppo oltre.
Il metodo (2) puo' essere combinato con una tecnica per la quale ti
risultera' abbastanza veloce riuscire a venire a conscenza della
dimensione del dispositivo, qualunque esso sia, ammesso che supporti la
lseek.
Questa tecninca consiste nel "lseekare" nel file a passi di potenze
crescenti di due, fino a quando una read() non ritorni EOF e memorizzando
sempre la posizione precedente. In questo modo sai che il file fininisce
tra l'ultima posizione corretta raggiunta e quella appena raggiunta. Ti
sposti quindi di nuovo all'ultima posizione corretta e ricominci il ciclo.
Questo procedimento lo ripeti fino a quando il "range d'azione" e'
ristretto ad un solo byte, essendo quel byte l'ultimo byte utile del file
di cui ti e' anche conosciuta la posizione (ultima+1). Questa posizione
rappresenta anche la lunghezza del file e quindi la dimensione del
dispositivo.
Questo codice ti puo' aiutare:
    unsigned long pos, oldpos, start = 0;
    do
    {
	pos = oldpos = 1;
	while (lseek(fd, start+pos, SEEK_SET)!=-1)
        {
	    int c;
	    if (read(fd, &c, 1) < 1) break;
	    oldpos = pos;
	    pos<<=1;
        }
	start+=oldpos;
    } while (pos-oldpos);
Alla fine in "start" troverai la dimensione del dispositivo, sia che sia
un floppy che un HD o qualsiasi altra cosa che supporti la lseek.
Stai attento, pero', che questo particolare codice funziona solo con
dispositivi che non sono piu' grandi di 2GB, in quanto lseek accetta come
parametro un intero con segno. Linux ha _llseek, che accetta un offset a
64bit diviso in word alta e bassa, usa quella per un algoritmo che
funzioni sempre (a meno di non possedere un HD di dimensioni
megafantascientifiche, che comunque non funzionerebbe con linux stesso :))
Fabio Alemagna

"Fabio Alemagna" ha scritto:
[...]
ti ringrazio, comunque ora guardo il codice di df e vedo come fa :)



df non ti servira' a molto, in quanto riporta la dimensione del
filesystem, che deve quindi essere montato. Per questo basta una semplice
statfs. Credimi, quella da me esposta, e' l'unica soluzione portabile
possibile sotto unix.
Fabio Alemagna

 portabile possibile sotto unix.
ma df mi distingue tra dischetti formattati a 2.8, 1.2, 1.4, mac e 720, 
la tua mi da' sempre 1.4 MB.... ovviamente non si limita a fare una 
statfs

On Fri, 27 Jul 2001, noname wrote:

df ha bisogno di un filesystem montato, e' il filesystem che poi utilizza
delle chiamate specifiche al driver del floppy disk per determinarne la
dimensione. L'algoritmo da me presentato funziona correttamente, e' il
device che apri che di default assume che il floppy sia di 1440Kb.
Anziche' /dev/fd0 prova ad aprire /dev/fd0u2880 e poi dimmi.
Se vuoi sapere l'esatta geometria del disco, e da lě derivare la
dimensione, allora devi utilizzare l'interfaccia del driver. Guarda in
/usr/include/linux/fd.h
Inoltre quando crei il filesystem sul disco devi specificarne la
dimensione, oppure utilizzare il device non generico (/dev/fd0????),
altrimenti ci sara' sempre l'assunzione che il floppy sia di 1440Kb.
fd usa stat, fidati :)
Fabio Alemagna

 fd usa stat, fidati :)
df o fd? se dici df, usa sia stat che stafs
________________________
/* tratto da fsusage.c, usato da show_dev in df.c */
int get_fs_usage (const char *path, const char *disk, struct fs_usage 
*fsp)
{
  struct statfs fsd;
  if (statfs (path, &fsd, sizeof (struct statfs)) != 0)
    return -1;
_________________________
/* tratto da df.c */
    for (i = optind; i < argc; ++i)
      {
        if (stat (argv[i], &stats[i - optind]))
cmq grazie, ti faro' sapere

"noname" ha scritto:
risolto, grazie al tuo consiglio di usare fd.h
se casomai servisse a qualcuno, e per gli archivi
per trovare la dimensione di un dischetto:
#include <linux/fd.h>
#include <ioctl.h>
#include <stdio.h>
#include <fcntl.h>
  floppy_struct geom;
  unsigned long disk_size;
  int fd, ioctl_res;
  fd = open("/dev/fd0",O_RDONLY);
  ioctl_res = ioctl(fd, FDGETPRM, &geom);
  close(fd);
  if (ioctl_res)   /* c'e' stato un errore, metto dimensione a zero */
    disk_size = 0;
  else             /* tutto okay */
    disk_size = geom.size *  FD_SECTSIZE(&geom);
grazie di nuovo