1 /* @(#)open.c 1.5 18/05/17 Copyright 2017-2018 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)open.c 1.5 18/05/17 Copyright 2017-2018 J. Schilling";
6 #endif
7 /*
8 * Open a StreamArchive
9 *
10 * Copyright (c) 2017-2018 J. Schilling
11 */
12 /*
13 * The contents of this file are subject to the terms of the
14 * Common Development and Distribution License, Version 1.0 only
15 * (the "License"). You may not use this file except in compliance
16 * with the License.
17 *
18 * See the file CDDL.Schily.txt in this distribution for details.
19 * A copy of the CDDL is also available via the Internet at
20 * http://www.opensource.org/licenses/cddl1.txt
21 *
22 * When distributing Covered Code, include this CDDL HEADER in each
23 * file and include the License file CDDL.Schily.txt from this distribution.
24 */
25
26 #include <schily/stdio.h>
27 #include <schily/utypes.h>
28 #include <schily/schily.h>
29 #include <schily/errno.h>
30 #include <schily/strar.h>
31 #include "header.h"
32
33 #define my_uid strar_my_uid
34 #define mode_mask strar_mode_mask
35 #define old_umask strar_old_umask
36
37 #define ROOT_UID 0
38
39 EXPORT uid_t my_uid;
40
41 /*
42 * This is used to allow extracting archives as non root when they
43 * contain read only directories. It tries to stay as close as possible
44 * to the user's umask when creating intermediate directories.
45 * We do not modify the umask in a way that would even grant unepected
46 * permissions to others for a short time.
47 */
48 EXPORT mode_t mode_mask;
49 EXPORT mode_t old_umask;
50
51 #define PERM_BITS (S_IRWXU|S_IRWXG|S_IRWXO) /* u/g/o basic perm */
52
53 LOCAL void init_umask __PR((void));
54
55 LOCAL void
init_umask()56 init_umask()
57 {
58 old_umask = umask((mode_t)0);
59 mode_mask = PERM_BITS & ~old_umask;
60 if (my_uid != ROOT_UID)
61 umask(old_umask & ~S_IRWXU);
62 else
63 umask(old_umask);
64 }
65
66 int
strar_open(info,arname,arfd,mode,codeset)67 strar_open(info, arname, arfd, mode, codeset)
68 register FINFO *info;
69 const char *arname;
70 int arfd;
71 int mode;
72 const char *codeset;
73 {
74 strar_init(info);
75
76 if (arname) {
77 info->f_fpname = arname;
78 if (mode & OM_ARFD) {
79 if ((info->f_fp = fileluopen(arfd,
80 (mode & OM_READ) ? "r":"wct")) == NULL)
81 return (-1);
82 } else if ((info->f_fp = fileopen(arname,
83 (mode & OM_READ) ? "r":"wct")) == NULL)
84 return (-1);
85 } else {
86 if (mode & OM_READ) {
87 info->f_fpname = "stdin";
88 info->f_fp = stdin;
89 } else if (mode & OM_WRITE) {
90 info->f_fpname = "stdout";
91 info->f_fp = stdout;
92 } else {
93 seterrno(EINVAL);
94 return (-1);
95 }
96 }
97 my_uid = geteuid();
98 init_umask();
99 utf8_codeset(codeset);
100 if (mode & OM_READ) {
101 utf8_init(S_EXTRACT);
102 } else if (mode & OM_WRITE) {
103 utf8_init(S_CREATE);
104 }
105
106 return (0);
107 }
108