OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libfs/] [src/] [dosfs/] [msdos_create.c] - Blame information for rev 1026

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
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
 * @(#) msdos_create.c,v 1.1 2002/02/28 20:43:50 joel Exp
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
 */
49
int
50
msdos_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
 
200
error:
201
    fat_file_close(parent_loc->mt_entry, fat_fd);
202
 
203
err:
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
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.