1 /* @(#)hparse.c	1.3 17/02/15 Copyright 2011-2017 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)hparse.c	1.3 17/02/15 Copyright 2011-2017 J. Schilling";
6 #endif
7 /*
8  *	Handling routines to parse a block of header entries from a
9  *	StreamArchive
10  *
11  *	Copyright (c) 2011-2017 J. Schilling
12  */
13 /*
14  * The contents of this file are subject to the terms of the
15  * Common Development and Distribution License, Version 1.0 only
16  * (the "License").  You may not use this file except in compliance
17  * with the License.
18  *
19  * See the file CDDL.Schily.txt in this distribution for details.
20  * A copy of the CDDL is also available via the Internet at
21  * http://www.opensource.org/licenses/cddl1.txt
22  *
23  * When distributing Covered Code, include this CDDL HEADER in each
24  * file and include the License file CDDL.Schily.txt from this distribution.
25  */
26 
27 #include <schily/stdio.h>
28 #include <schily/utypes.h>
29 #include <schily/string.h>
30 #include <schily/schily.h>
31 #include <schily/strar.h>
32 #include "header.h"
33 #include "table.h"
34 
35 EXPORT void
strar_reset(info)36 strar_reset(info)
37 	register strar	*info;
38 {
39 	info->f_mode = 0;
40 	info->f_size = 0;
41 	info->f_rsize = 0;
42 	info->f_xflags = 0;
43 	info->f_status = 0;
44 	info->f_xftype = info->f_rxftype = XT_NONE;
45 	info->f_atime = info->f_mtime = info->f_ctime = 0;
46 	info->f_name[0] = '\0';
47 	info->f_lname[0] = '\0';
48 	info->f_uid = info->f_gid = 0;
49 	info->f_uname = NULL;
50 	info->f_gname = NULL;
51 }
52 
53 EXPORT BOOL
strar_hparse(info)54 strar_hparse(info)
55 	register strar	*info;
56 {
57 	register char	*p;
58 	register char	*ep;
59 		long	length;
60 		int	c;
61 		int	i;
62 		FILE	*f = info->f_fp;
63 
64 again:
65 	strar_xbreset();
66 	if (strar_gxblen() < 10)
67 		strar_xbgrow(10);
68 
69 	/*
70 	 * Fetch the length element to know about the size of the next field.
71 	 */
72 	p = ep = strar_gxbuf();
73 	length = 0;
74 	for (i = 0; (c = getc(f)) != EOF && i < 10; i++) {
75 		*p++ = c;
76 		if (c >= '0' && c <= '9') {
77 			length *= 10;
78 			length += c - '0';
79 		} else if (c == ' ') {
80 			break;
81 		} else {
82 			return (FALSE);	/* SYNTAX ERROR */
83 		}
84 	}
85 	if (feof(f)) {
86 		return (FALSE);
87 	}
88 	if (strar_gxblen() < length) {
89 		size_t	off = p - ep;
90 
91 		strar_xbgrow(length);
92 		p = ep = strar_gxbuf();
93 		p += off;
94 	}
95 	fileread(f, p, length - i - 1);
96 
97 	p = strar_gxbuf();
98 	ep = p + length;
99 
100 	i = strar_xhparse(info, p, ep);
101 	if (i > TRUE) {
102 		/*
103 		 * Allow a minimalistic archive.
104 		 */
105 		if ((info->f_xflags & XF_FILETYPE) == 0)
106 			info->f_rxftype = XT_FILE;
107 		/*
108 		 * If there is no arfiletype (e.g. "hardlink")
109 		 * set it to the real file type.
110 		 */
111 		if (info->f_xftype == XT_NONE)
112 			info->f_xftype = info->f_rxftype;
113 
114 		if ((info->f_xflags & XF_MODE) == 0)
115 			info->f_mode = 0666;
116 		return (TRUE);
117 	}
118 	if (i > 0)
119 		goto again;
120 	return (i);
121 }
122