Subversion Repositories Kolibri OS

Rev

Rev 6725 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6725 siemargl 1
/*
2
Kolibri OS port for gcc 5.4
3
 
4
Started by Siemargl @Nov 2016
5
 
6
Contains realisation of directory handling functions:
7
    mkdir()
8
    closedir()
9
    opendir()
10
    readdir()
11
    rewinddir()
12
 
13
    !!non reentrant
14
*/
15
 
16
#include 
17
#include 
18
#include 
19
#include 
20
#include 
21
#include 
22
#include "kos32sys1.h"
23
 
24
/* defined in newlib headers
25
int	_EXFUN(mkdir,( const char *_path, mode_t __mode ));
26
 
27
struct dirent {
28
  char d_namlen;
29
  char d_name[256];
30
};
31
 
32
typedef struct
33
{
34
//    struct systree_info2 fileinfo;
35
    struct dirent entry;
36
//    __u8 bdfeheader[0x20];
37
//    struct bdfe_item bdfebase;
38
//    __u8 bdfename[264];
39
} DIR;
40
 
41
int     closedir(DIR *dirp);
42
DIR *       opendir(const char *_dirname);
43
struct dirent * readdir(DIR *_dirp);
44
void      rewinddir(DIR *_dirp);
45
*/
46
 
47
static int32_t lastread_block = -1; // non reentrant, must me -1ed in closedir, or will assert
48
static uint32_t lastread_dir_size;
49
static DIR  lastread_dir;
50
 
51
DIR *opendir(const char *_dirname)
52
{
53
    assert(sizeof(struct fs_dirinfo) == 25);  // check struct aligment
54
    assert(lastread_block == -1);
55
 
56
    struct fs_dirinfo di;
57
    struct fs_dirheader dhead;
58
 
59
    memset(&di, 0, sizeof di);
60
    di.ppath = (char*)_dirname;
61
    di.retval = (uint32_t)&dhead;
62
    int rc = sf_file(1, &di);  // read dir size
63
    if(rc) {
64
        fprintf(stderr, "Error reading dir size %s\n", _dirname);
65
        errno = rc;
66
        return NULL;
67
    }
68
    lastread_dir_size = dhead.totl_blocks;
69
 
70
    lastread_dir.entry.d_namlen = strlen(_dirname);
71
    assert (lastread_dir.entry.d_namlen < sizeof(lastread_dir.entry.d_name));
72
    strcpy(lastread_dir.entry.d_name, _dirname);
73
 
74
    return &lastread_dir;
75
};
76
 
77
 
78
int closedir(DIR *dirp)
79
{
80
    assert (lastread_block != -1);  // was opened
81
 
82
    if (!dirp || lastread_block == -1)
83
    {
84
        errno = EBADF;
85
        return -1;
86
    }
87
    lastread_block = -1;
88
    lastread_dir_size = 0;
89
    lastread_dir.entry.d_namlen = 0;
90
    lastread_dir.entry.d_name[0] = '\0';
91
 
92
    return 0;
93
};
94
 
95
 
96
struct dirent* readdir(DIR *dirp)
97
{
98
    assert (lastread_block != -1);  // was opened
99
 
100
    if (!dirp || lastread_block == -1)
101
    {
102
        errno = EBADF;
103
        return NULL;
104
    }
105
    struct fs_dirinfo di;
106
 
107
    assert (lastread_block != -1);  // was opened
108
 
109
    char retdir[sizeof(struct fs_dirheader) + sizeof(struct fsBDFE)];   // 1 block w/cp866 encoding
110
    struct fsBDFE *bdfe = (struct fsBDFE *)(retdir + sizeof(struct fs_dirheader));
111
    memset(&di, 0, sizeof di);
112
    di.ppath = dirp->entry.d_name;
113
    di.retval = (uint32_t)retdir;
114
    di.start = lastread_block;
115
    di.size = 1;
116
 
117
    int rc = sf_file(1, &di);  // read dir
118
    if(rc) {
6727 siemargl 119
        fprintf(stderr, "Error %d reading dir item %s\n", rc, dirp->entry.d_name);
6725 siemargl 120
        errno = rc;
121
        return NULL;
122
    }
123
 
124
    static struct dirent ent;
125
    ent.d_namlen = strlen(bdfe->fname);
126
    assert (ent.d_namlen < sizeof(ent.d_name));
127
    strcpy(ent.d_name, bdfe->fname);
128
    lastread_block++;
129
 
130
    return &ent;
131
};
132
 
133
 
134
void rewinddir(DIR *dirp)
135
{
136
    if (!dirp || lastread_block == -1)
137
    {
138
        return;
139
    }
140
 
141
    lastread_block = 0;
142
}
143
 
144
 
145
int	mkdir(const char *_path, mode_t m)
146
{
6727 siemargl 147
    char   namebuffer[1050]; // need for save data after di!!!
148
    struct fs_dirinfo *di = (struct fs_dirinfo *)namebuffer;
6725 siemargl 149
 
6727 siemargl 150
debug_board_printf("mkdir start (%s)\n", _path);
151
    memset(di, 0, sizeof(struct fs_dirinfo));
152
    //di.ppath = (char*)_path;  // dont work with 70.9
153
    strcpy(di->path, _path);
154
 
155
    int rc = sf_file(9, di);  // creat dir
6725 siemargl 156
    if(rc) {
6727 siemargl 157
        fprintf(stderr, "Error %d creating dir item %s\n", rc, _path);
6725 siemargl 158
        errno = rc;
159
        return -1;
160
    }
161
 
6727 siemargl 162
debug_board_printf("mkdir end (%s)\n", _path);
6725 siemargl 163
    return 0;
164
}
165
 
6727 siemargl 166
////////////////////////////////////////////////////////////////////////////////////////
167
void __attribute__ ((noinline)) debug_board_write_str(const char* str){
168
  while(*str)
169
    debug_board_write_byte(*str++);
170
}
6725 siemargl 171
 
6727 siemargl 172
void __attribute__ ((noinline)) debug_board_printf(const char *format,...)
173
{
174
        va_list ap;
175
        char log_board[300];
176
 
177
        va_start (ap, format);
178
        vsnprintf(log_board, sizeof log_board, format, ap);
179
        va_end(ap);
180
        debug_board_write_str(log_board);
181
}
182
 
183
__attribute__ ((noinline)) void trap(int n)
184
{
185
    // nothing todo, just see n in debugger. use "bp trap" command
186
    __asm__ __volatile__(
187
    "nop"
188
    :
189
    :"a"(n));
190
}
191
 
192
 
193
 
6725 siemargl 194
/* tested example
195
void* read_folderdata(char* name)
196
{
197
    struct fs_dirinfo di;
198
    struct fs_dirheader dhead;
199
    assert(sizeof di == 25);
200
 
201
    memset(&di, 0, sizeof di);
202
    di.ppath = name;
203
    di.retval = (uint32_t)&dhead;
204
    int rc = sf_file(1, &di);  // read dir size
205
    if(rc) {
206
        debug_board_printf("Error reading dir size %s", name);
207
        exit(1);
208
    }
209
    di.size = dhead.totl_blocks;
210
 
211
    char *retdir = malloc(sizeof dhead + dhead.totl_blocks * sizeof(struct fsBDFE));
212
    if(!retdir) {
213
        debug_board_printf("No memory for dir %s", name);
214
        exit(1);
215
    }
216
    di.retval = (uint32_t)retdir;
217
    rc = sf_file(1, &di);  // read dir
218
    if(rc) {
219
        debug_board_printf("Error 2 reading dir size %s", name);
220
        exit(1);
221
    }
222
 
223
    // manual clear mark flag (random junk in fname free space)
224
    int i;
225
    for (i = 0; i < dhead.totl_blocks; i++)
226
        ((struct fsBDFE*)(retdir+32))[i].fname[259] = 0;
227
 
228
    debug_board_printf("Loaded dir [%s] etnries %d,\n first file [%s]\n", name, ((struct fs_dirheader*)(retdir))->curn_blocks, ((struct fsBDFE*)(retdir+32))->fname);
229
 
230
    return retdir;
231
}
232
*/