]> git.saurik.com Git - apple/security.git/blob - SecurityTool/readline.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTool / readline.c
1 /*
2 * Copyright (c) 2003-2004,2012,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 *
23 * readline.c
24 */
25
26 #include "readline.h"
27 #include "security.h"
28
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35
36 /* Read a line from stdin into buffer as a null terminated string. If buffer is
37 non NULL use at most buffer_size bytes and return a pointer to buffer. Otherwise
38 return a newly malloced buffer.
39 if EOF is read this function returns NULL. */
40 char *
41 readline(char *buffer, int buffer_size)
42 {
43 int ix = 0, bytes_malloced = 0;
44
45 if (!buffer)
46 {
47 bytes_malloced = 64;
48 buffer = (char *)malloc(bytes_malloced);
49 buffer_size = bytes_malloced;
50 }
51
52 for (;;++ix)
53 {
54 int ch;
55
56 if (ix == buffer_size - 1)
57 {
58 if (!bytes_malloced)
59 break;
60 bytes_malloced += bytes_malloced;
61 buffer = (char *)realloc(buffer, bytes_malloced);
62 buffer_size = bytes_malloced;
63 }
64
65 ch = getchar();
66 if (ch == EOF)
67 {
68 if (bytes_malloced)
69 free(buffer);
70 return NULL;
71 }
72 if (ch == '\n')
73 break;
74 buffer[ix] = ch;
75 }
76
77 /* 0 terminate buffer. */
78 buffer[ix] = '\0';
79
80 return buffer;
81 }
82
83 /* Read the file name into buffer. On return buffer contains a newly
84 malloced buffer or length buffer_size. Return 0 on success and -1 on failure. */
85 int
86 read_file(const char *name, CSSM_DATA *outData)
87 {
88 int fd, result;
89 char *buffer = NULL;
90 off_t length;
91 ssize_t bytes_read;
92
93 do {
94 fd = open(name, O_RDONLY, 0);
95 } while (fd == -1 && errno == EINTR);
96
97 if (fd == -1)
98 {
99 sec_error("open %s: %s", name, strerror(errno));
100 result = -1;
101 goto loser;
102 }
103
104 length = lseek(fd, 0, SEEK_END);
105 if (length == -1)
106 {
107 sec_error("lseek %s, SEEK_END: %s", name, strerror(errno));
108 result = -1;
109 goto loser;
110 }
111
112 buffer = malloc(length);
113
114 do {
115 bytes_read = pread(fd, buffer, length, 0);
116 } while (bytes_read == -1 && errno == EINTR);
117
118 if (bytes_read == -1)
119 {
120 sec_error("pread %s: %s", name, strerror(errno));
121 result = -1;
122 goto loser;
123 }
124 if (bytes_read != (ssize_t)length)
125 {
126 sec_error("read %s: only read %d of %qu bytes", name, bytes_read, length);
127 result = -1;
128 goto loser;
129 }
130
131 do {
132 result = close(fd);
133 } while (result == -1 && errno == EINTR);
134 if (result == -1)
135 {
136 sec_error("close %s: %s", name, strerror(errno));
137 goto loser;
138 }
139
140 outData->Data = (uint8 *)buffer;
141 outData->Length = (uint32)length;
142
143 return result;
144
145 loser:
146 if (buffer)
147 free(buffer);
148
149 return result;
150 }