syslinux-3.08-2 sources from FC4
[bootcd.git] / syslinux / libfat / searchdir.c
1 #ident "$Id: searchdir.c,v 1.2 2005/01/04 03:04:54 hpa Exp $"
2 /* ----------------------------------------------------------------------- *
3  *   
4  *   Copyright 2004 H. Peter Anvin - All Rights Reserved
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
9  *   Boston MA 02111-1307, USA; either version 2 of the License, or
10  *   (at your option) any later version; incorporated herein by reference.
11  *
12  * ----------------------------------------------------------------------- */
13
14 /*
15  * searchdir.c
16  *
17  * Search a FAT directory for a particular pre-mangled filename.
18  * Copies the directory entry into direntry and returns the starting cluster
19  * if found; returns -2 on not found, -1 on error, 0 on empty file.
20  */
21
22 #include <string.h>
23 #include "libfatint.h"
24
25 int32_t libfat_searchdir(struct libfat_filesystem *fs, int32_t dirclust,
26                          const void *name, struct libfat_direntry *direntry)
27 {
28   struct fat_dirent *dep;
29   int nent;
30   libfat_sector_t s = libfat_clustertosector(fs, dirclust);
31
32   while ( 1 ) {
33     if ( s == 0 )
34       return -2;                /* Not found */
35     else if ( s == (libfat_sector_t)-1 )
36       return -1;                /* Error */
37     
38     dep = libfat_get_sector(fs, s);
39     if ( !dep )
40       return -1;                /* Read error */
41
42     for ( nent = 0 ; nent < LIBFAT_SECTOR_SIZE ;
43           nent += sizeof(struct fat_dirent) ) {
44       if ( !memcmp(dep->name, name, 11) ) {
45         if ( direntry ) {
46           memcpy(direntry->entry, dep, sizeof (*dep));
47           direntry->sector = s;
48           direntry->offset = nent;
49         }
50         if ( read32(&dep->size) == 0 )
51           return 0;             /* An empty file has no clusters */
52         else
53           return read16(&dep->clustlo) + (read16(&dep->clusthi) << 16);
54       }
55       
56       if ( dep->name[0] == 0 )
57         return -2;              /* Hit high water mark */
58
59       dep++;
60     }   
61
62     s = libfat_nextsector(fs, s);
63   }
64 }