]>
git.saurik.com Git - apple/xnu.git/blob - SETUP/replacecontents/replacecontents.c
2 * Copyright (c) 2013 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
34 #include <sys/fcntl.h>
35 #include <sys/param.h>
41 main(int argc
, char * argv
[])
44 char *newcontent
= NULL
;
45 size_t newcontentlength
= 0;
46 char *oldcontent
= NULL
;
49 const char *dst
= NULL
;
50 ssize_t readsize
, writesize
;
59 for (i
= 2; i
< argc
; i
++) {
60 newcontentlength
+= strlen(argv
[i
]) + 1 /* space or newline */;
62 newcontentlength
+= 1; /* NUL */
64 newcontent
= malloc(newcontentlength
);
65 if (newcontent
== NULL
) {
66 err(EX_UNAVAILABLE
, "malloc() failed");
71 for (i
= 2; i
< argc
; i
++) {
72 strlcat(newcontent
, argv
[i
], newcontentlength
);
74 strlcat(newcontent
, " ", newcontentlength
);
76 strlcat(newcontent
, "\n", newcontentlength
);
80 dstfd
= open(dst
, O_RDWR
| O_CREAT
| O_APPEND
, DEFFILEMODE
);
82 err(EX_NOINPUT
, "open(%s)", dst
);
85 ret
= fstat(dstfd
, &sb
);
87 err(EX_NOINPUT
, "fstat(%s)", dst
);
90 if (!S_ISREG(sb
.st_mode
)) {
91 err(EX_USAGE
, "%s is not a regular file", dst
);
94 if (sb
.st_size
!= newcontentlength
) {
95 /* obvious new content must be different than old */
99 oldcontent
= malloc(newcontentlength
);
100 if (oldcontent
== NULL
) {
101 err(EX_UNAVAILABLE
, "malloc(%lu) failed", newcontentlength
);
104 readsize
= read(dstfd
, oldcontent
, newcontentlength
);
105 if (readsize
== -1) {
106 err(EX_UNAVAILABLE
, "read() failed");
107 } else if (readsize
!= newcontentlength
) {
108 errx(EX_UNAVAILABLE
, "short read of file");
111 if (0 == memcmp(oldcontent
, newcontent
, newcontentlength
)) {
112 /* binary comparison succeeded, just exit */
116 err(EX_UNAVAILABLE
, "close() failed");
123 ret
= ftruncate(dstfd
, 0);
125 err(EX_UNAVAILABLE
, "ftruncate() failed");
128 writesize
= write(dstfd
, newcontent
, newcontentlength
);
129 if (writesize
== -1) {
130 err(EX_UNAVAILABLE
, "write() failed");
131 } else if (writesize
!= newcontentlength
) {
132 errx(EX_UNAVAILABLE
, "short write of file");
137 err(EX_NOINPUT
, "close(dst)");
146 fprintf(stderr
, "Usage: %s <dst> <new> <contents> <...>\n",