summaryrefslogtreecommitdiff
path: root/directory.c
diff options
context:
space:
mode:
Diffstat (limited to 'directory.c')
-rw-r--r--directory.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/directory.c b/directory.c
new file mode 100644
index 0000000..12c3ec0
--- /dev/null
+++ b/directory.c
@@ -0,0 +1,143 @@
+/* Copyright 1995 David C. Niemi
+ * Copyright 1996-2002,2008,2009 Alain Knaff.
+ * This file is part of mtools.
+ *
+ * Mtools is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mtools is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "sysincludes.h"
+#include "msdos.h"
+#include "stream.h"
+#include "mtools.h"
+#include "file.h"
+#include "fs.h"
+#include "file_name.h"
+
+/* #define DEBUG */
+
+/*
+ * Read a directory entry into caller supplied buffer
+ */
+struct directory *dir_read(direntry_t *entry, int *error)
+{
+ int n;
+ *error = 0;
+ if((n=force_read(entry->Dir, (char *) (&entry->dir),
+ (mt_off_t) entry->entry * MDIR_SIZE,
+ MDIR_SIZE)) != MDIR_SIZE) {
+ if (n < 0) {
+ *error = -1;
+ }
+ return NULL;
+ }
+ return &entry->dir;
+}
+
+/*
+ * Make a subdirectory grow in length. Only subdirectories (not root)
+ * may grow. Returns a 0 on success, 1 on failure (disk full), or -1
+ * on error.
+ */
+
+int dir_grow(Stream_t *Dir, int size)
+{
+ Stream_t *Stream = GetFs(Dir);
+ DeclareThis(FsPublic_t);
+ int ret;
+ int buflen;
+ char *buffer;
+
+ if (!getfreeMinClusters(Dir, 1))
+ return -1;
+
+ buflen = This->cluster_size * This->sector_size;
+
+ if(! (buffer=malloc(buflen)) ){
+ perror("dir_grow: malloc");
+ return -1;
+ }
+
+ memset((char *) buffer, '\0', buflen);
+ ret = force_write(Dir, buffer, (mt_off_t) size * MDIR_SIZE, buflen);
+ free(buffer);
+ if(ret < buflen)
+ return -1;
+ return 0;
+}
+
+
+void low_level_dir_write(direntry_t *entry)
+{
+ force_write(entry->Dir,
+ (char *) (&entry->dir),
+ (mt_off_t) entry->entry * MDIR_SIZE, MDIR_SIZE);
+}
+
+void low_level_dir_write_end(Stream_t *Dir, int entry)
+{
+ char zero = ENDMARK;
+ force_write(Dir, &zero, (mt_off_t) entry * MDIR_SIZE, 1);
+}
+
+/*
+ * Make a directory entry. Builds a directory entry based on the
+ * name, attribute, starting cluster number, and size. Returns a pointer
+ * to a static directory structure.
+ */
+
+struct directory *mk_entry(const dos_name_t *dn, char attr,
+ unsigned int fat, size_t size, time_t date,
+ struct directory *ndir)
+{
+ struct tm *now;
+ time_t date2 = date;
+ unsigned char hour, min_hi, min_low, sec;
+ unsigned char year, month_hi, month_low, day;
+
+ now = localtime(&date2);
+ dosnameToDirentry(dn, ndir);
+ ndir->attr = attr;
+ ndir->ctime_ms = 0;
+ hour = now->tm_hour << 3;
+ min_hi = now->tm_min >> 3;
+ min_low = now->tm_min << 5;
+ sec = now->tm_sec / 2;
+ ndir->ctime[1] = ndir->time[1] = hour + min_hi;
+ ndir->ctime[0] = ndir->time[0] = min_low + sec;
+ year = (now->tm_year - 80) << 1;
+ month_hi = (now->tm_mon + 1) >> 3;
+ month_low = (now->tm_mon + 1) << 5;
+ day = now->tm_mday;
+ ndir -> adate[1] = ndir->cdate[1] = ndir->date[1] = year + month_hi;
+ ndir -> adate[0] = ndir->cdate[0] = ndir->date[0] = month_low + day;
+
+ set_word(ndir->start, fat & 0xffff);
+ set_word(ndir->startHi, fat >> 16);
+ set_dword(ndir->size, size);
+ return ndir;
+}
+
+/*
+ * Make a directory entry from base name. This is supposed to be used
+ * from places such as mmd for making special entries (".", "..", "/", ...)
+ * Thus it doesn't bother with character set conversions
+ */
+struct directory *mk_entry_from_base(const char *base, char attr,
+ unsigned int fat, size_t size, time_t date,
+ struct directory *ndir)
+{
+ struct dos_name_t dn;
+ strncpy(dn.base, base, 8);
+ strncpy(dn.ext, " ", 3);
+ return mk_entry(&dn, attr, fat, size, date, ndir);
+}