source: rtems/cpukit/libfs/src/dosfs/msdos_create.c @ f36a7bfc

4.104.114.84.95
Last change on this file since f36a7bfc was f36a7bfc, checked in by Joel Sherrill <joel.sherrill@…>, on Feb 28, 2002 at 8:43:50 PM

2002-02-28 Victor V. Vengerov <vvv@…>

  • DOS filesystem including FAT12, FAT16, and FAT32 support submitted.
  • src/dosfs, src/dosfs/Makefile.am, src/dosfs/stamp-h2.in, src/dosfs/config.h.in, src/dosfs/dosfs.h, src/dosfs/fat.c, src/dosfs/fat.h, src/dosfs/fat_fat_operations.c, src/dosfs/fat_fat_operations.h, src/dosfs/fat_file.c, src/dosfs/fat_file.h, src/dosfs/msdos.h, src/dosfs/msdos_create.c, src/dosfs/msdos_dir.c, src/dosfs/msdos_eval.c, src/dosfs/msdos_file.c, src/dosfs/msdos_free.c, src/dosfs/msdos_fsunmount.c, src/dosfs/msdos_handlers_dir.c, src/dosfs/msdos_handlers_file.c, src/dosfs/msdos_init.c, src/dosfs/msdos_initsupp.c, src/dosfs/msdos_misc.c, src/dosfs/msdos_mknod.c, src/dosfs/msdos_node_type.c, src/dosfs/.cvsignore: New files.
  • configure.ac, src/Makefile.am, wrapup/Makefile.am: Modified to reflect addition.
  • Property mode set to 100644
File size: 6.9 KB
Line 
1/*
2 * Routine to create a new MSDOS filesystem node
3 *
4 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
5 * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
6 *
7 * The license and distribution terms for this file may be
8 * found in the file LICENSE in this distribution or at
9 * http://www.OARcorp.com/rtems/license.html.
10 *
11 * @(#) $Id$
12 *
13 */
14#if HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#include <errno.h>
19#include <assert.h>
20#include <stdlib.h>
21#include <string.h>
22#include <rtems/libio_.h>
23#include <time.h>
24
25#include "fat.h"
26#include "fat_fat_operations.h"
27#include "fat_file.h"
28
29#include "msdos.h"
30
31/* msdos_creat_node --
32 *     Create a new node. If a new node is file, FAT 32 Bytes Directory
33 *     Entry Structure (see M$ White Paper) is initialized, free space is
34 *     found in parent directory and structure is written to the disk.
35 *     In case of directory, all above steps present and also new cluster
36 *     is allocated for a new directory and dot and dotdot nodes are created
37 *     in alloceted cluster.
38 *
39 * PARAMETERS:
40 *     parent_loc - parent (directory we are going to create node in)
41 *     type       - new node type (file or directory)
42 *     name       - new node name
43 *     mode       - mode
44 *
45 * RETURNS:
46 *     RC_OK on success, or -1 if error occured (errno set appropriately).
47 *     
48 */
49int 
50msdos_creat_node(
51    rtems_filesystem_location_info_t  *parent_loc,
52    msdos_node_type_t                  type,
53    char                              *name,
54    mode_t                             mode
55    ) 
56{
57    int              rc = RC_OK;
58    ssize_t          ret = 0;
59    msdos_fs_info_t *fs_info = parent_loc->mt_entry->fs_info;
60    fat_file_fd_t   *parent_fat_fd = parent_loc->node_access;
61    fat_file_fd_t   *fat_fd = NULL; 
62    time_t           time_ret = 0;
63    unsigned16       time_val = 0;
64    unsigned16       date = 0;
65    fat_auxiliary_t  aux;
66    unsigned char    new_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
67    unsigned char    dot_dotdot[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2];
68   
69    memset(new_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
70    memset(dot_dotdot, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2);
71 
72    /* set up name */
73    strncpy(MSDOS_DIR_NAME(new_node), name, MSDOS_NAME_MAX);
74
75    /* fill reserved field */
76    *MSDOS_DIR_NT_RES(new_node) = MSDOS_RES_NT_VALUE;
77 
78    /* set up last write date and time */
79    time_ret = time(NULL);
80    if ( time_ret == -1 )
81        return -1;
82
83    msdos_date_unix2dos(time_ret, &time_val, &date);
84    *MSDOS_DIR_WRITE_TIME(new_node) = CT_LE_W(time_val);
85    *MSDOS_DIR_WRITE_DATE(new_node) = CT_LE_W(date);
86 
87    /* initialize directory/file size */
88    *MSDOS_DIR_FILE_SIZE(new_node) = MSDOS_INIT_DIR_SIZE;
89
90    if (type == MSDOS_DIRECTORY)
91        *MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_DIRECTORY;
92    else
93        *MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_ARCHIVE;
94
95    /*
96     * find free space in the parent directory and write new initialized
97     * FAT 32 Bytes Directory Entry Structure (see M$ White Paper)
98     * to the disk
99     */
100    rc = msdos_get_name_node(parent_loc, NULL, &aux, new_node);
101    if ( rc != RC_OK )
102        return rc;
103 
104    /*
105     * if we create a new file we are done, if directory there are more steps
106     * to do
107     */
108    if (type == MSDOS_DIRECTORY)
109    {
110        /* open new directory as fat-file */
111        rc = fat_file_open(parent_loc->mt_entry, aux.cln, aux.ofs, &fat_fd);
112        if (rc != RC_OK)
113            goto err;
114
115        /*
116         * we opened fat-file for node we just created, so initialize fat-file
117         * descritor
118         */
119        fat_fd->info_cln = aux.cln;
120        fat_fd->info_ofs = aux.ofs;
121        fat_fd->fat_file_size = 0;
122        fat_fd->fat_file_type = FAT_DIRECTORY;
123        fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT;
124   
125        /*
126         * dot and dotdot entries are identical to new node except the
127         * names
128         */
129        memcpy(DOT_NODE_P(dot_dotdot), new_node, 
130               MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); 
131        memcpy(DOTDOT_NODE_P(dot_dotdot), new_node,
132               MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); 
133        memcpy(MSDOS_DIR_NAME(DOT_NODE_P(dot_dotdot)), MSDOS_DOT_NAME, 
134               MSDOS_NAME_MAX);
135        memcpy(MSDOS_DIR_NAME(DOTDOT_NODE_P(dot_dotdot)), MSDOS_DOTDOT_NAME, 
136               MSDOS_NAME_MAX);
137           
138        /* set up cluster num for dotdot entry */
139        /*
140         * here we can ommit FAT32 condition because for all FAT types dirs
141         * right under root dir should contain 0 in dotdot entry but for
142         * FAT12/16 parent_fat_fd->cluster_num always contains such value
143         */   
144        if ((FAT_FD_OF_ROOT_DIR(parent_fat_fd)) && 
145            (fs_info->fat.vol.type & FAT_FAT32))
146        {
147            *MSDOS_DIR_FIRST_CLUSTER_LOW(DOTDOT_NODE_P(dot_dotdot)) = 0x0000;
148            *MSDOS_DIR_FIRST_CLUSTER_HI(DOTDOT_NODE_P(dot_dotdot)) = 0x0000;
149        }
150        else
151        {
152            *MSDOS_DIR_FIRST_CLUSTER_LOW(DOTDOT_NODE_P(dot_dotdot)) = 
153                CT_LE_W((unsigned16)((parent_fat_fd->cln) & 0x0000FFFF));
154            *MSDOS_DIR_FIRST_CLUSTER_HI(DOTDOT_NODE_P(dot_dotdot)) = 
155                CT_LE_W((unsigned16)(((parent_fat_fd->cln) & 0xFFFF0000)>>16));
156        }       
157   
158        /*
159         * write dot and dotdot entries to new fat-file: currently fat-file
160         * correspondes to a new node is zero length, so it will be extended
161         * by one cluster and entries will be written
162         */
163        ret = fat_file_write(parent_loc->mt_entry, fat_fd, 0, 
164                             MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2, 
165                             dot_dotdot);
166        if (ret < 0)
167        {
168            rc = -1;
169            goto error;
170        }
171   
172        /* increment fat-file size by cluster size */
173        fat_fd->fat_file_size += fs_info->fat.vol.bpc;
174
175        /* set up cluster num for dot entry */
176        *MSDOS_DIR_FIRST_CLUSTER_LOW(DOT_NODE_P(dot_dotdot)) =
177                CT_LE_W((unsigned16)((fat_fd->cln) & 0x0000FFFF));
178        *MSDOS_DIR_FIRST_CLUSTER_HI(DOT_NODE_P(dot_dotdot)) =
179                CT_LE_W((unsigned16)(((fat_fd->cln) & 0xFFFF0000) >> 16));
180
181        /* rewrite dot entry */
182        ret = fat_file_write(parent_loc->mt_entry, fat_fd, 0, 
183                             MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE,
184                             DOT_NODE_P(dot_dotdot));
185        if (ret < 0)
186        {
187            rc = -1;
188            goto error;
189        }
190   
191        /* write first cluster num of a new directory to disk */
192        rc = msdos_set_first_cluster_num(parent_loc->mt_entry, fat_fd);   
193        if (rc != RC_OK)
194            goto error;         
195 
196        fat_file_close(parent_loc->mt_entry, fat_fd);
197    }
198    return RC_OK;
199
200error:
201    fat_file_close(parent_loc->mt_entry, fat_fd);
202
203err:
204    /* mark 32bytes structure on the disk as free */
205    msdos_set_first_char4file_name(parent_loc->mt_entry, aux.cln, aux.ofs, 
206                                   0xE5);
207    return rc;
208}
Note: See TracBrowser for help on using the repository browser.