74 |
int patch_level; |
int patch_level; |
75 |
int ret = 0; |
int ret = 0; |
76 |
char plus = '+'; |
char plus = '+'; |
77 |
|
unsigned opt; |
78 |
|
enum { |
79 |
|
OPT_R = (1 << 2), |
80 |
|
OPT_N = (1 << 3), |
81 |
|
/*OPT_f = (1 << 4), ignored */ |
82 |
|
/*OPT_E = (1 << 5), ignored, this is the default */ |
83 |
|
/*OPT_g = (1 << 6), ignored */ |
84 |
|
OPT_dry_run = (1 << 7) * ENABLE_LONG_OPTS, |
85 |
|
}; |
86 |
|
|
87 |
xfunc_error_retval = 2; |
xfunc_error_retval = 2; |
88 |
{ |
{ |
89 |
const char *p = "-1"; |
const char *p = "-1"; |
90 |
const char *i = "-"; /* compat */ |
const char *i = "-"; /* compat */ |
91 |
if (getopt32(argv, "p:i:R", &p, &i) & 4) |
#if ENABLE_LONG_OPTS |
92 |
|
static const char patch_longopts[] ALIGN1 = |
93 |
|
"strip\0" Required_argument "p" |
94 |
|
"input\0" Required_argument "i" |
95 |
|
"reverse\0" No_argument "R" |
96 |
|
"forward\0" No_argument "N" |
97 |
|
/* "Assume user knows what [s]he is doing, do not ask any questions": */ |
98 |
|
"force\0" No_argument "f" /*ignored*/ |
99 |
|
# if ENABLE_DESKTOP |
100 |
|
"remove-empty-files\0" No_argument "E" /*ignored*/ |
101 |
|
/* "Controls actions when a file is under RCS or SCCS control, |
102 |
|
* and does not exist or is read-only and matches the default version, |
103 |
|
* or when a file is under ClearCase control and does not exist..." |
104 |
|
* IOW: rather obscure option. |
105 |
|
* But Gentoo's portage does use -g0 */ |
106 |
|
"get\0" Required_argument "g" /*ignored*/ |
107 |
|
# endif |
108 |
|
"dry-run\0" No_argument "\xfd" |
109 |
|
# if ENABLE_DESKTOP |
110 |
|
"backup-if-mismatch\0" No_argument "\xfe" /*ignored*/ |
111 |
|
"no-backup-if-mismatch\0" No_argument "\xff" /*ignored*/ |
112 |
|
# endif |
113 |
|
; |
114 |
|
applet_long_options = patch_longopts; |
115 |
|
#endif |
116 |
|
/* -f,-E,-g are ignored */ |
117 |
|
opt = getopt32(argv, "p:i:RN""fEg:", &p, &i, NULL); |
118 |
|
if (opt & OPT_R) |
119 |
plus = '-'; |
plus = '-'; |
120 |
patch_level = xatoi(p); /* can be negative! */ |
patch_level = xatoi(p); /* can be negative! */ |
121 |
patch_file = xfopen_stdin(i); |
patch_file = xfopen_stdin(i); |
127 |
FILE *dst_stream; |
FILE *dst_stream; |
128 |
//char *old_filename; |
//char *old_filename; |
129 |
char *new_filename; |
char *new_filename; |
130 |
char *backup_filename; |
char *backup_filename = NULL; |
131 |
unsigned src_cur_line = 1; |
unsigned src_cur_line = 1; |
132 |
unsigned dst_cur_line = 0; |
unsigned dst_cur_line = 0; |
133 |
unsigned dst_beg_line; |
unsigned dst_beg_line; |
161 |
bb_make_directory(new_filename, -1, FILEUTILS_RECUR); |
bb_make_directory(new_filename, -1, FILEUTILS_RECUR); |
162 |
*slash = '/'; |
*slash = '/'; |
163 |
} |
} |
|
backup_filename = NULL; |
|
164 |
src_stream = NULL; |
src_stream = NULL; |
165 |
saved_stat.st_mode = 0644; |
saved_stat.st_mode = 0644; |
166 |
} else { |
} else if (!(opt & OPT_dry_run)) { |
167 |
backup_filename = xasprintf("%s.orig", new_filename); |
backup_filename = xasprintf("%s.orig", new_filename); |
168 |
xrename(new_filename, backup_filename); |
xrename(new_filename, backup_filename); |
169 |
src_stream = xfopen_for_read(backup_filename); |
src_stream = xfopen_for_read(backup_filename); |
170 |
|
} else |
171 |
|
src_stream = xfopen_for_read(new_filename); |
172 |
|
|
173 |
|
if (opt & OPT_dry_run) { |
174 |
|
dst_stream = xfopen_for_write("/dev/null"); |
175 |
|
} else { |
176 |
|
dst_stream = xfopen_for_write(new_filename); |
177 |
|
fchmod(fileno(dst_stream), saved_stat.st_mode); |
178 |
} |
} |
|
dst_stream = xfopen_for_write(new_filename); |
|
|
fchmod(fileno(dst_stream), saved_stat.st_mode); |
|
179 |
|
|
180 |
printf("patching file %s\n", new_filename); |
printf("patching file %s\n", new_filename); |
181 |
|
|
224 |
patch_line = xmalloc_fgets(patch_file); |
patch_line = xmalloc_fgets(patch_file); |
225 |
if (patch_line == NULL) |
if (patch_line == NULL) |
226 |
break; /* EOF */ |
break; /* EOF */ |
227 |
|
if (!*patch_line) { |
228 |
|
/* whitespace-damaged patch with "" lines */ |
229 |
|
free(patch_line); |
230 |
|
patch_line = xstrdup(" "); |
231 |
|
} |
232 |
if ((*patch_line != '-') && (*patch_line != '+') |
if ((*patch_line != '-') && (*patch_line != '+') |
233 |
&& (*patch_line != ' ') |
&& (*patch_line != ' ') |
234 |
) { |
) { |
248 |
src_line = NULL; |
src_line = NULL; |
249 |
} |
} |
250 |
} |
} |
251 |
|
/* Do not patch an already patched hunk with -N */ |
252 |
|
if (src_line == 0 && (opt & OPT_N)) { |
253 |
|
continue; |
254 |
|
} |
255 |
if (!src_line) { |
if (!src_line) { |
256 |
bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start); |
bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start); |
257 |
bad_hunk_count++; |
bad_hunk_count++; |
284 |
if (backup_filename) { |
if (backup_filename) { |
285 |
unlink(backup_filename); |
unlink(backup_filename); |
286 |
} |
} |
287 |
if ((dst_cur_line == 0) || (dst_beg_line == 0)) { |
if (!(opt & OPT_dry_run) |
288 |
|
&& ((dst_cur_line == 0) || (dst_beg_line == 0)) |
289 |
|
) { |
290 |
/* The new patched file is empty, remove it */ |
/* The new patched file is empty, remove it */ |
291 |
xunlink(new_filename); |
xunlink(new_filename); |
292 |
// /* old_filename and new_filename may be the same file */ |
// /* old_filename and new_filename may be the same file */ |