This repository has been archived by the owner on Oct 29, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
device.c
204 lines (161 loc) · 5.46 KB
/
device.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#include "device.h"
struct device_metadata{
char check[6];
int buffer_size;
int block_count;
int format_status;
};
struct device_opened_in_table{
int buffer_size;
int block_count;
int format_status;
FILE *file;
};
static struct device_opened_in_table device_table[MAX_OPENED];
int dev_format(char *name, int block_size, int block_count)
{
//no puede haber un block size o cantidad de bloques negativos
if (block_size <= 0 || block_count < 0)
return INVALID_PARAMETERS;
int i;
//creamos el archivo en blanco y si ya existe se formatea
FILE *f;
f = fopen(name, "w");
//chequeamos que se pudo crear
if (f == NULL)
return CANNOT_CREATE_DEVICE;//printf("Cannot create file %s\n", name);
//printf("%d", sizeof(struct file_inodo));
//creamos el inodo de el archivo en especifico
struct device_metadata metadata;
strncpy(metadata.check, "Hola!", 6);//en el espacio del nombre ponemos la palabra "Hola!" para poder revisar que es un archivo formateado por este api
metadata.buffer_size = block_size;
metadata.block_count = block_count;
metadata.format_status = 0;
//escribimos el inodo especifico del archivo
fwrite(&metadata, 1, sizeof(struct device_metadata), f);
//creamos un buffer de tamano especificado y creamos una cantidad de bloques especificada
char *buffer = (char *) malloc(block_size);
memset(buffer, 0, block_size);
for (i = 0; i < block_count; i++)
fwrite(buffer, 1, block_size, f);
fclose(f);
free(buffer);
return SUCCESS;
}
int dev_open(char *name)
{
int i;
//abrimos el archivo en modo lectura y escritura
FILE *f = fopen(name, "r+");
struct device_metadata metadata;
//revisamos que no hayan problemas
if (f == NULL)
return CANNOT_ACCESS_DEVICE;
//leemos el inodo especifico del archivo
fread(&metadata, 1, sizeof(struct device_metadata), f);
//chequea si tiene la palabra clave de nuestro formateo, "Hola!"
if (strcmp(metadata.check, "Hola!"))
{
fclose(f);
return FORMAT_NOT_ALLOWED;
}
//busca cual esta vacio
for (i = 0; i < MAX_OPENED; i++)
{
if (device_table[i].file == NULL)
break;
//si la tabla esta llena no lo guarda y cierra el FILE
if (i == MAX_OPENED - 1)
{
fclose(f);
return EXTERNAL_INVALID_PARAMETERS;
}
}
//reescribe el inodo a la tabla
device_table[i].block_count = metadata.block_count;
device_table[i].buffer_size = metadata.buffer_size;
device_table[i].format_status = metadata.format_status;
device_table[i].file = f;
return i;
}
int dev_write_block(int dh, char *buffer, int block_index)
{
//chequea si el dh es aceptable, si el archivo esta abierto y si el bloque existe
if (dh < 0 || dh >= MAX_OPENED)
return INVALID_PARAMETERS;//printf("File %s\n not opened", device_table[dh].name);
if (block_index < 0 || device_table[dh].block_count <= block_index || device_table[dh].file == NULL)
return EXTERNAL_INVALID_PARAMETERS;
//se mueve al bloque que va a escribir incluyendo el sizeof(struct file_inodo) del inodo personal de cada archivo
fseek(device_table[dh].file, (block_index*device_table[dh].buffer_size) + sizeof(struct device_metadata), SEEK_SET);
fwrite(buffer, 1, device_table[dh].buffer_size, device_table[dh].file);
return SUCCESS;
}
int dev_read_block(int dh, char *buffer, int block_index)
{
//chequea si el dh es aceptable, si el archivo esta abierto y si el bloque existe
if (dh < 0 || dh >= MAX_OPENED)
return INVALID_PARAMETERS;//printf("File %s\n not opened", device_table[dh].name);
if (block_index < 0 || device_table[dh].block_count <= block_index || device_table[dh].file == NULL)
return EXTERNAL_INVALID_PARAMETERS;
//se mueve al bloque que va a leer incluyendo el sizeof(struct file_inodo) del inodo personal de cada archivo
fseek(device_table[dh].file, (block_index*device_table[dh].buffer_size) + sizeof(struct device_metadata), SEEK_SET);
fread(buffer, 1, device_table[dh].buffer_size, device_table[dh].file);
return SUCCESS;
}
int dev_close(int dh)
{
//chequea si el dh es aceptable
if (dh < 0 || dh >= MAX_OPENED)
return INVALID_PARAMETERS;
//chequiamos si el archivo esta abierto
if (device_table[dh].file == NULL)
return CANNOT_ACCESS_DEVICE;
//lo cerramos y lo ponemos en NULL en el arreglo
fclose(device_table[dh].file);
device_table[dh].file = NULL;
return SUCCESS;
}
int dev_get_buffer_size(int dh)
{
return device_table[dh].buffer_size;
}
int dev_get_block_count(int dh)
{
return device_table[dh].block_count;
}
FILE* dev_get_file(int dh)
{
fseek(device_table[dh].file, 0, SEEK_CUR);
return device_table[dh].file;
}
int dev_is_format(int dh)
{
//chequea si el dh es aceptable
if (dh < 0 || dh >= MAX_OPENED)
return INVALID_PARAMETERS;
//chequiamos si el archivo esta abierto
if (device_table[dh].file == NULL)
return CANNOT_ACCESS_DEVICE;
return device_table[dh].format_status;
}
int dev_set_format(int dh)
{
//chequea si el dh es aceptable
if (dh < 0 || dh >= MAX_OPENED)
return INVALID_PARAMETERS;
//chequiamos si el archivo esta abierto
if (device_table[dh].file == NULL)
return CANNOT_ACCESS_DEVICE;
//creamos nuestro struct para cambiar el format status
struct device_metadata metadata;
//leemos el inodo especifico del archivo
fseek(device_table[dh].file, 0, SEEK_SET);
fread(&metadata, 1, sizeof(struct device_metadata), device_table[dh].file);
//escribimos que esta formateado en el archivo y el
metadata.format_status = 1;
device_table[dh].format_status = 1;
//escribimos en el archivo
fseek(device_table[dh].file, 0, SEEK_SET);
fwrite(&metadata, 1, sizeof(struct device_metadata), device_table[dh].file);
return SUCCESS;
}