1 /* Copyright 1995 David C. Niemi
2 * Copyright 1996-2002,2008,2009 Alain Knaff.
3 * This file is part of mtools.
5 * Mtools is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * Mtools is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
18 #include "sysincludes.h"
24 #include "file_name.h"
29 * Read a directory entry into caller supplied buffer
31 struct directory *dir_read(direntry_t *entry, int *error)
35 if((n=force_read(entry->Dir, (char *) (&entry->dir),
36 (mt_off_t) entry->entry * MDIR_SIZE,
37 MDIR_SIZE)) != MDIR_SIZE) {
47 * Make a subdirectory grow in length. Only subdirectories (not root)
48 * may grow. Returns a 0 on success, 1 on failure (disk full), or -1
52 int dir_grow(Stream_t *Dir, int size)
54 Stream_t *Stream = GetFs(Dir);
55 DeclareThis(FsPublic_t);
60 if (!getfreeMinClusters(Dir, 1))
63 buflen = This->cluster_size * This->sector_size;
65 if(! (buffer=malloc(buflen)) ){
66 perror("dir_grow: malloc");
70 memset((char *) buffer, '\0', buflen);
71 ret = force_write(Dir, buffer, (mt_off_t) size * MDIR_SIZE, buflen);
79 void low_level_dir_write(direntry_t *entry)
81 force_write(entry->Dir,
82 (char *) (&entry->dir),
83 (mt_off_t) entry->entry * MDIR_SIZE, MDIR_SIZE);
88 * Make a directory entry. Builds a directory entry based on the
89 * name, attribute, starting cluster number, and size. Returns a pointer
90 * to a static directory structure.
93 struct directory *mk_entry(const dos_name_t *dn, char attr,
94 unsigned int fat, size_t size, time_t date,
95 struct directory *ndir)
99 unsigned char hour, min_hi, min_low, sec;
100 unsigned char year, month_hi, month_low, day;
102 now = localtime(&date2);
103 dosnameToDirentry(dn, ndir);
106 hour = now->tm_hour << 3;
107 min_hi = now->tm_min >> 3;
108 min_low = now->tm_min << 5;
109 sec = now->tm_sec / 2;
110 ndir->ctime[1] = ndir->time[1] = hour + min_hi;
111 ndir->ctime[0] = ndir->time[0] = min_low + sec;
112 year = (now->tm_year - 80) << 1;
113 month_hi = (now->tm_mon + 1) >> 3;
114 month_low = (now->tm_mon + 1) << 5;
116 ndir -> adate[1] = ndir->cdate[1] = ndir->date[1] = year + month_hi;
117 ndir -> adate[0] = ndir->cdate[0] = ndir->date[0] = month_low + day;
119 set_word(ndir->start, fat & 0xffff);
120 set_word(ndir->startHi, fat >> 16);
121 set_dword(ndir->size, size);
126 * Make a directory entry from base name. This is supposed to be used
127 * from places such as mmd for making special entries (".", "..", "/", ...)
128 * Thus it doesn't bother with character set conversions
130 struct directory *mk_entry_from_base(const char *base, char attr,
131 unsigned int fat, size_t size, time_t date,
132 struct directory *ndir)
134 struct dos_name_t dn;
135 strncpy(dn.base, base, 8);
136 strncpy(dn.ext, " ", 3);
137 return mk_entry(&dn, attr, fat, size, date, ndir);