embox

Форк
0
129 строк · 3.5 Кб
1
/**
2
 * @file
3
 * @brief CPIO file format.
4
 *
5
 * @date 29.09.10
6
 * @author Nikolay Korotky
7
 * @author Eldar Abusalimov
8
 *          - Rewrite from scratch, no more dependencies on initfs.
9
 */
10

11
#include <cpio.h>
12

13
#include <stdlib.h>
14
#include <string.h>
15
#include <stdio.h>
16
#include <sys/stat.h>
17

18
#include <fs/fs_driver.h>
19
#include <kernel/printk.h>
20

21
/**
22
 * The pathname is followed by NUL bytes so that the total size of the fixed
23
 * header plus pathname is a multiple of four. Likewise, the file data is
24
 * padded to a multiple of four bytes.
25
 */
26
#define NEWC_NAME_ALIGN(len) ((((len) + 1) & ~3) + 2)
27
#define NEWC_FILE_ALIGN(len) (((len) + 3) & ~3)
28

29
/* Value for the field `c_magic'.  */
30
#define NEWC_MAGIC       "070701"
31
#define OLD_BIN_MAGIC    "070707"
32

33
#define NEWC_FIELD_SZ     8
34

35
/* New ASCII Format */
36
struct newc_hdr {
37
	char c_magic[sizeof(NEWC_MAGIC) - 1]; /**< Must be "070701". */
38
	char c_ino[NEWC_FIELD_SZ];       /**< The inode numbers from the disk. */
39
	char c_mode[NEWC_FIELD_SZ];      /**< Permissions and the file type.*/
40
	char c_uid[NEWC_FIELD_SZ];       /**< User id of the owner. */
41
	char c_gid[NEWC_FIELD_SZ];       /**< Group id of the owner. */
42
	char c_nlink[NEWC_FIELD_SZ];     /**< The number of links to this file.*/
43
	char c_mtime[NEWC_FIELD_SZ];     /**< Modification time, seconds. */
44
	char c_filesize[NEWC_FIELD_SZ];  /**< Zero for FIFOs and directories. */
45
	char c_devmajor[NEWC_FIELD_SZ];
46
	char c_devminor[NEWC_FIELD_SZ];
47
	char c_rdevmajor[NEWC_FIELD_SZ];
48
	char c_rdevminor[NEWC_FIELD_SZ];
49
	char c_namesize[NEWC_FIELD_SZ];  /**< Bytes in the pathname.*/
50
	char c_check[NEWC_FIELD_SZ];     /**< Ignored, must be zero. */
51
};
52

53
struct newc_hdr_parsed {
54
	unsigned long ino;
55
	unsigned long mode;
56
	unsigned long uid;
57
	unsigned long gid;
58
	unsigned long nlink;
59
	unsigned long mtime;
60
	unsigned long filesize;
61
	unsigned long devmajor;
62
	unsigned long devminor;
63
	unsigned long rdevmajor;
64
	unsigned long rdevminor;
65
	unsigned long namesize;
66
};
67

68
#define STR_LEN_TUPLE(str) (str), (sizeof(str) - 1)
69

70
static char *cpio_parse_newc(const struct newc_hdr *hdr,
71
		struct cpio_entry *entry) {
72
	char *raw = (char *) hdr + sizeof(hdr->c_magic);
73
	struct newc_hdr_parsed parsed;
74
	char field_buff[NEWC_FIELD_SZ + 1];
75

76
	field_buff[NEWC_FIELD_SZ] = '\0';
77

78
	for (unsigned long *p_field = (unsigned long *) &parsed;
79
	     p_field < (unsigned long *) (&parsed + 1);
80
	     ++p_field, raw += NEWC_FIELD_SZ) {
81
		unsigned long tmp;
82

83
		memcpy(field_buff, raw, NEWC_FIELD_SZ);
84
		tmp = strtol(field_buff, NULL, 16);
85
		memcpy(p_field, &tmp, sizeof *p_field);
86
	}
87

88
	raw += NEWC_FIELD_SZ; /* skip c_check field, now raw points to name. */
89

90
	if (strncmp(raw, STR_LEN_TUPLE("TRAILER!!!")) == 0) {
91
		return NULL;
92
	}
93

94
	entry->mode  = parsed.mode;
95
	entry->uid   = parsed.uid;
96
	entry->gid   = parsed.gid;
97
	entry->mtime = parsed.mtime;
98
#if 0
99
	entry->ino   = parsed.ino;
100
	entry->nlink = parsed.nlink;
101
	entry->devmajor = parsed.devmajor;
102
	entry->devminor = parsed.devminor;
103
	entry->rdevmajor = parsed.rdevmajor;
104
	entry->rdevminor = parsed.rdevminor;
105
#endif
106

107
	entry->name = raw;
108
	entry->name_len = parsed.namesize;
109
	raw += NEWC_NAME_ALIGN(parsed.namesize);
110

111
	entry->data = raw;
112
	entry->size = parsed.filesize;
113
	raw += NEWC_FILE_ALIGN(parsed.filesize);
114

115
	return raw;
116
}
117

118
char *cpio_parse_entry(const char *cpio, struct cpio_entry *entry) {
119
	if (memcmp(cpio, STR_LEN_TUPLE(OLD_BIN_MAGIC)) == 0) {
120
		printk("Use -H newc option for create CPIO archive\n");
121
		return NULL;
122
	}
123
	if (memcmp(cpio, STR_LEN_TUPLE(NEWC_MAGIC)) != 0) {
124
		printk("Newc ASCII CPIO format not recognized\n");
125
		return NULL;
126
	}
127

128
	return cpio_parse_newc((struct newc_hdr *) cpio, entry);
129
}
130

131

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.