wok annotate busybox/stuff/busybox-1.10.3-patch.u @ rev 859

Up: busybox (1.10.3)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Jun 05 08:00:51 2008 +0000 (2008-06-05)
parents
children
rev   line source
pascal@859 1 --- busybox-1.10.3/editors/patch.c 2008-03-24 15:46:20.000000000 +0100
pascal@859 2 +++ busybox-1.10.3/editors/patch.c 2008-03-24 15:46:20.000000000 +0100
pascal@859 3 @@ -19,15 +19,11 @@
pascal@859 4 * - Reject file isnt saved
pascal@859 5 */
pascal@859 6
pascal@859 7 -#include <getopt.h>
pascal@859 8 -
pascal@859 9 #include "libbb.h"
pascal@859 10
pascal@859 11 -static unsigned int copy_lines(FILE *src_stream, FILE *dest_stream, const unsigned int lines_count)
pascal@859 12 +static unsigned copy_lines(FILE *src_stream, FILE *dest_stream, unsigned lines_count)
pascal@859 13 {
pascal@859 14 - unsigned int i = 0;
pascal@859 15 -
pascal@859 16 - while (src_stream && (i < lines_count)) {
pascal@859 17 + while (src_stream && lines_count) {
pascal@859 18 char *line;
pascal@859 19 line = xmalloc_fgets(src_stream);
pascal@859 20 if (line == NULL) {
pascal@859 21 @@ -37,60 +33,70 @@
pascal@859 22 bb_perror_msg_and_die("error writing to new file");
pascal@859 23 }
pascal@859 24 free(line);
pascal@859 25 -
pascal@859 26 - i++;
pascal@859 27 + lines_count--;
pascal@859 28 }
pascal@859 29 - return i;
pascal@859 30 + return lines_count;
pascal@859 31 }
pascal@859 32
pascal@859 33 /* If patch_level is -1 it will remove all directory names
pascal@859 34 * char *line must be greater than 4 chars
pascal@859 35 * returns NULL if the file doesnt exist or error
pascal@859 36 * returns malloc'ed filename
pascal@859 37 + * NB: frees 1st argument!
pascal@859 38 */
pascal@859 39
pascal@859 40 -static char *extract_filename(char *line, int patch_level)
pascal@859 41 +static char *extract_filename(char *line, unsigned patch_level, const char *pat)
pascal@859 42 {
pascal@859 43 - char *temp, *filename_start_ptr = line + 4;
pascal@859 44 - int i;
pascal@859 45 + char *temp = NULL, *filename_start_ptr = line + 4;
pascal@859 46
pascal@859 47 - /* Terminate string at end of source filename */
pascal@859 48 - temp = strchrnul(filename_start_ptr, '\t');
pascal@859 49 - *temp = '\0';
pascal@859 50 -
pascal@859 51 - /* Skip over (patch_level) number of leading directories */
pascal@859 52 - if (patch_level == -1)
pascal@859 53 - patch_level = INT_MAX;
pascal@859 54 - for (i = 0; i < patch_level; i++) {
pascal@859 55 - temp = strchr(filename_start_ptr, '/');
pascal@859 56 - if (!temp)
pascal@859 57 - break;
pascal@859 58 - filename_start_ptr = temp + 1;
pascal@859 59 + if (strncmp(line, pat, 4) == 0) {
pascal@859 60 + /* Terminate string at end of source filename */
pascal@859 61 + line[strcspn(line,"\t\n\r")] = '\0';
pascal@859 62 +
pascal@859 63 + /* Skip over (patch_level) number of leading directories */
pascal@859 64 + while (patch_level--) {
pascal@859 65 + temp = strchr(filename_start_ptr, '/');
pascal@859 66 + if (!temp)
pascal@859 67 + break;
pascal@859 68 + filename_start_ptr = temp + 1;
pascal@859 69 + }
pascal@859 70 + temp = xstrdup(filename_start_ptr);
pascal@859 71 }
pascal@859 72 -
pascal@859 73 - return xstrdup(filename_start_ptr);
pascal@859 74 + free(line);
pascal@859 75 + return temp;
pascal@859 76 }
pascal@859 77
pascal@859 78 int patch_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
pascal@859 79 int patch_main(int argc ATTRIBUTE_UNUSED, char **argv)
pascal@859 80 {
pascal@859 81 - int patch_level = -1;
pascal@859 82 - char *patch_line;
pascal@859 83 - int ret;
pascal@859 84 - FILE *patch_file = NULL;
pascal@859 85 struct stat saved_stat;
pascal@859 86 -
pascal@859 87 + char *patch_line;
pascal@859 88 + FILE *patch_file;
pascal@859 89 + int patch_level;
pascal@859 90 + int ret = 0;
pascal@859 91 +#define ENABLE_FEATURE_PATCH_REVERSE 1
pascal@859 92 +#if ENABLE_FEATURE_PATCH_REVERSE
pascal@859 93 + char minus = '-';
pascal@859 94 + char plus = '+';
pascal@859 95 +#else
pascal@859 96 + const char minus = '-';
pascal@859 97 + const char plus = '+';
pascal@859 98 +#endif
pascal@859 99 +
pascal@859 100 + xfunc_error_retval = 2;
pascal@859 101 {
pascal@859 102 - char *p, *i;
pascal@859 103 - ret = getopt32(argv, "p:i:", &p, &i);
pascal@859 104 - if (ret & 1)
pascal@859 105 - patch_level = xatol_range(p, -1, USHRT_MAX);
pascal@859 106 - if (ret & 2) {
pascal@859 107 - patch_file = xfopen(i, "r");
pascal@859 108 - } else {
pascal@859 109 - patch_file = stdin;
pascal@859 110 - }
pascal@859 111 - ret = 0;
pascal@859 112 + const char *p = "-1";
pascal@859 113 + const char *i = "-"; /* compat */
pascal@859 114 +#if ENABLE_FEATURE_PATCH_REVERSE
pascal@859 115 + if (getopt32(argv, "p:i:R", &p, &i) & 4) {
pascal@859 116 + minus = '+';
pascal@859 117 + plus = '-';
pascal@859 118 + }
pascal@859 119 +#else
pascal@859 120 + getopt32(argv, "p:i:", &p, &i);
pascal@859 121 +#endif
pascal@859 122 + patch_level = xatoi(p); /* can be negative! */
pascal@859 123 + patch_file = xfopen_stdin(i);
pascal@859 124 }
pascal@859 125
pascal@859 126 patch_line = xmalloc_getline(patch_file);
pascal@859 127 @@ -100,38 +106,38 @@
pascal@859 128 char *original_filename;
pascal@859 129 char *new_filename;
pascal@859 130 char *backup_filename;
pascal@859 131 - unsigned int src_cur_line = 1;
pascal@859 132 - unsigned int dest_cur_line = 0;
pascal@859 133 - unsigned int dest_beg_line;
pascal@859 134 - unsigned int bad_hunk_count = 0;
pascal@859 135 - unsigned int hunk_count = 0;
pascal@859 136 - char copy_trailing_lines_flag = 0;
pascal@859 137 + unsigned src_cur_line = 1;
pascal@859 138 + unsigned dest_cur_line = 0;
pascal@859 139 + unsigned dest_beg_line;
pascal@859 140 + unsigned bad_hunk_count = 0;
pascal@859 141 + unsigned hunk_count = 0;
pascal@859 142 + smallint copy_trailing_lines_flag = 0;
pascal@859 143
pascal@859 144 /* Skip everything upto the "---" marker
pascal@859 145 * No need to parse the lines "Only in <dir>", and "diff <args>"
pascal@859 146 */
pascal@859 147 - while (patch_line && strncmp(patch_line, "--- ", 4) != 0) {
pascal@859 148 - free(patch_line);
pascal@859 149 + do {
pascal@859 150 + /* Extract the filename used before the patch was generated */
pascal@859 151 + original_filename = extract_filename(patch_line, patch_level, "--- ");
pascal@859 152 patch_line = xmalloc_getline(patch_file);
pascal@859 153 - }
pascal@859 154 - /* FIXME: patch_line NULL check?? */
pascal@859 155 + if (!patch_line) goto quit;
pascal@859 156 + } while (!original_filename);
pascal@859 157
pascal@859 158 - /* Extract the filename used before the patch was generated */
pascal@859 159 - original_filename = extract_filename(patch_line, patch_level);
pascal@859 160 - free(patch_line);
pascal@859 161 -
pascal@859 162 - patch_line = xmalloc_getline(patch_file);
pascal@859 163 - /* FIXME: NULL check?? */
pascal@859 164 - if (strncmp(patch_line, "+++ ", 4) != 0) {
pascal@859 165 - ret = 2;
pascal@859 166 - bb_error_msg("invalid patch");
pascal@859 167 - continue;
pascal@859 168 + new_filename = extract_filename(patch_line, patch_level, "+++ ");
pascal@859 169 + if (!new_filename) {
pascal@859 170 + bb_error_msg_and_die("invalid patch");
pascal@859 171 + }
pascal@859 172 +#if ENABLE_FEATURE_PATCH_REVERSE
pascal@859 173 + if (plus != '+') {
pascal@859 174 + /* reverse patch */
pascal@859 175 + char *tmp = original_filename;
pascal@859 176 + original_filename = new_filename;
pascal@859 177 + new_filename = tmp;
pascal@859 178 }
pascal@859 179 - new_filename = extract_filename(patch_line, patch_level);
pascal@859 180 - free(patch_line);
pascal@859 181 +#endif
pascal@859 182
pascal@859 183 /* Get access rights from the file to be patched, -1 file does not exist */
pascal@859 184 - if (stat(new_filename, &saved_stat)) {
pascal@859 185 + if (stat(new_filename, &saved_stat) != 0) {
pascal@859 186 char *line_ptr;
pascal@859 187 /* Create leading directories */
pascal@859 188 line_ptr = strrchr(new_filename, '/');
pascal@859 189 @@ -140,132 +146,137 @@
pascal@859 190 bb_make_directory(new_filename, -1, FILEUTILS_RECUR);
pascal@859 191 *line_ptr = '/';
pascal@859 192 }
pascal@859 193 - dst_stream = xfopen(new_filename, "w+");
pascal@859 194 backup_filename = NULL;
pascal@859 195 + saved_stat.st_mode = 0644;
pascal@859 196 } else {
pascal@859 197 - backup_filename = xmalloc(strlen(new_filename) + 6);
pascal@859 198 - strcpy(backup_filename, new_filename);
pascal@859 199 - strcat(backup_filename, ".orig");
pascal@859 200 + backup_filename = xasprintf("%s.orig", new_filename);
pascal@859 201 xrename(new_filename, backup_filename);
pascal@859 202 - dst_stream = xfopen(new_filename, "w");
pascal@859 203 - fchmod(fileno(dst_stream), saved_stat.st_mode);
pascal@859 204 }
pascal@859 205 -
pascal@859 206 - if ((backup_filename == NULL) || stat(original_filename, &saved_stat)) {
pascal@859 207 - src_stream = NULL;
pascal@859 208 - } else {
pascal@859 209 - if (strcmp(original_filename, new_filename) == 0) {
pascal@859 210 - src_stream = xfopen(backup_filename, "r");
pascal@859 211 - } else {
pascal@859 212 - src_stream = xfopen(original_filename, "r");
pascal@859 213 - }
pascal@859 214 + dst_stream = xfopen(new_filename, "w");
pascal@859 215 + fchmod(fileno(dst_stream), saved_stat.st_mode);
pascal@859 216 + src_stream = NULL;
pascal@859 217 +
pascal@859 218 + if (backup_filename && !stat(original_filename, &saved_stat)) {
pascal@859 219 + src_stream = xfopen((strcmp(original_filename, new_filename)) ?
pascal@859 220 + original_filename : backup_filename, "r");
pascal@859 221 }
pascal@859 222
pascal@859 223 printf("patching file %s\n", new_filename);
pascal@859 224
pascal@859 225 - /* Handle each hunk */
pascal@859 226 + /* Handle all hunks for this file */
pascal@859 227 patch_line = xmalloc_fgets(patch_file);
pascal@859 228 while (patch_line) {
pascal@859 229 - unsigned int count;
pascal@859 230 - unsigned int src_beg_line;
pascal@859 231 - unsigned int unused;
pascal@859 232 - unsigned int hunk_offset_start = 0;
pascal@859 233 - int hunk_error = 0;
pascal@859 234 -
pascal@859 235 - /* This bit should be improved */
pascal@859 236 - if ((sscanf(patch_line, "@@ -%d,%d +%d,%d @@", &src_beg_line, &unused, &dest_beg_line, &unused) != 4) &&
pascal@859 237 - (sscanf(patch_line, "@@ -%d,%d +%d @@", &src_beg_line, &unused, &dest_beg_line) != 3) &&
pascal@859 238 - (sscanf(patch_line, "@@ -%d +%d,%d @@", &src_beg_line, &dest_beg_line, &unused) != 3)) {
pascal@859 239 + unsigned count;
pascal@859 240 + unsigned src_beg_line;
pascal@859 241 + unsigned hunk_offset_start;
pascal@859 242 + unsigned src_last_line = 1;
pascal@859 243 +#if ENABLE_FEATURE_PATCH_REVERSE
pascal@859 244 + unsigned dst_last_line = 1;
pascal@859 245 +
pascal@859 246 + if ((sscanf(patch_line, "@@ -%d,%d +%d,%d", &src_beg_line, &src_last_line, &dest_beg_line, &dst_last_line) < 3) &&
pascal@859 247 + (sscanf(patch_line, "@@ -%d +%d,%d", &src_beg_line, &dest_beg_line, &dst_last_line) < 2)) {
pascal@859 248 /* No more hunks for this file */
pascal@859 249 break;
pascal@859 250 }
pascal@859 251 - free(patch_line);
pascal@859 252 + if (plus != '+') {
pascal@859 253 + /* reverse patch */
pascal@859 254 + unsigned tmp = src_last_line;
pascal@859 255 + src_last_line = dst_last_line;
pascal@859 256 + dst_last_line = tmp;
pascal@859 257 + tmp = src_beg_line;
pascal@859 258 + src_beg_line = dest_beg_line;
pascal@859 259 + dest_beg_line = tmp;
pascal@859 260 + }
pascal@859 261 +#else
pascal@859 262 +
pascal@859 263 + if ((sscanf(patch_line, "@@ -%d,%d +%d", &src_beg_line, &src_last_line, &dest_beg_line) != 3) &&
pascal@859 264 + (sscanf(patch_line, "@@ -%d +%d", &src_beg_line, &dest_beg_line) != 2)) {
pascal@859 265 + /* No more hunks for this file */
pascal@859 266 + break;
pascal@859 267 + }
pascal@859 268 +#endif
pascal@859 269 hunk_count++;
pascal@859 270
pascal@859 271 if (src_beg_line && dest_beg_line) {
pascal@859 272 /* Copy unmodified lines upto start of hunk */
pascal@859 273 - /* src_beg_line will be 0 if its a new file */
pascal@859 274 + /* src_beg_line will be 0 if it's a new file */
pascal@859 275 count = src_beg_line - src_cur_line;
pascal@859 276 - if (copy_lines(src_stream, dst_stream, count) != count) {
pascal@859 277 + if (copy_lines(src_stream, dst_stream, count)) {
pascal@859 278 bb_error_msg_and_die("bad src file");
pascal@859 279 }
pascal@859 280 src_cur_line += count;
pascal@859 281 dest_cur_line += count;
pascal@859 282 copy_trailing_lines_flag = 1;
pascal@859 283 }
pascal@859 284 - hunk_offset_start = src_cur_line;
pascal@859 285 -
pascal@859 286 - while ((patch_line = xmalloc_fgets(patch_file)) != NULL) {
pascal@859 287 - if ((*patch_line == '-') || (*patch_line == ' ')) {
pascal@859 288 + src_last_line += hunk_offset_start = src_cur_line;
pascal@859 289 +#if ENABLE_FEATURE_PATCH_REVERSE
pascal@859 290 + dst_last_line += dest_cur_line;
pascal@859 291 +#endif
pascal@859 292 + while (1) {
pascal@859 293 + free(patch_line);
pascal@859 294 + patch_line = xmalloc_fgets(patch_file);
pascal@859 295 + if (patch_line == NULL) break;
pascal@859 296 + if ((*patch_line == minus) || (*patch_line == ' ')) {
pascal@859 297 char *src_line = NULL;
pascal@859 298 + if (src_cur_line == src_last_line) break;
pascal@859 299 if (src_stream) {
pascal@859 300 src_line = xmalloc_fgets(src_stream);
pascal@859 301 - if (!src_line) {
pascal@859 302 - hunk_error++;
pascal@859 303 - break;
pascal@859 304 - } else {
pascal@859 305 + if (src_line) {
pascal@859 306 + int diff = strcmp(src_line, patch_line + 1);
pascal@859 307 src_cur_line++;
pascal@859 308 + free(src_line);
pascal@859 309 + if (diff) src_line = NULL;
pascal@859 310 }
pascal@859 311 - if (strcmp(src_line, patch_line + 1) != 0) {
pascal@859 312 - bb_error_msg("hunk #%d FAILED at %d", hunk_count, hunk_offset_start);
pascal@859 313 - hunk_error++;
pascal@859 314 - free(patch_line);
pascal@859 315 - /* Probably need to find next hunk, etc... */
pascal@859 316 - /* but for now we just bail out */
pascal@859 317 - patch_line = NULL;
pascal@859 318 - break;
pascal@859 319 - }
pascal@859 320 - free(src_line);
pascal@859 321 }
pascal@859 322 - if (*patch_line == ' ') {
pascal@859 323 - fputs(patch_line + 1, dst_stream);
pascal@859 324 - dest_cur_line++;
pascal@859 325 + if (!src_line) {
pascal@859 326 + bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start);
pascal@859 327 + bad_hunk_count++;
pascal@859 328 + break;
pascal@859 329 }
pascal@859 330 - } else if (*patch_line == '+') {
pascal@859 331 - fputs(patch_line + 1, dst_stream);
pascal@859 332 - dest_cur_line++;
pascal@859 333 - } else {
pascal@859 334 + if (*patch_line != ' ') {
pascal@859 335 + continue;
pascal@859 336 + }
pascal@859 337 + } else if (*patch_line != plus) {
pascal@859 338 break;
pascal@859 339 }
pascal@859 340 - free(patch_line);
pascal@859 341 - }
pascal@859 342 - if (hunk_error) {
pascal@859 343 - bad_hunk_count++;
pascal@859 344 - }
pascal@859 345 - }
pascal@859 346 +#if ENABLE_FEATURE_PATCH_REVERSE
pascal@859 347 + if (dest_cur_line == dst_last_line) break;
pascal@859 348 +#endif
pascal@859 349 + fputs(patch_line + 1, dst_stream);
pascal@859 350 + dest_cur_line++;
pascal@859 351 + } /* end of while loop handling one hunk */
pascal@859 352 + } /* end of while loop handling one file */
pascal@859 353
pascal@859 354 /* Cleanup last patched file */
pascal@859 355 if (copy_trailing_lines_flag) {
pascal@859 356 - copy_lines(src_stream, dst_stream, -1);
pascal@859 357 + copy_lines(src_stream, dst_stream, (unsigned)(-1));
pascal@859 358 }
pascal@859 359 if (src_stream) {
pascal@859 360 fclose(src_stream);
pascal@859 361 }
pascal@859 362 - if (dst_stream) {
pascal@859 363 - fclose(dst_stream);
pascal@859 364 - }
pascal@859 365 + fclose(dst_stream);
pascal@859 366 if (bad_hunk_count) {
pascal@859 367 - if (!ret) {
pascal@859 368 - ret = 1;
pascal@859 369 - }
pascal@859 370 - bb_error_msg("%d out of %d hunk FAILED", bad_hunk_count, hunk_count);
pascal@859 371 + ret = 1;
pascal@859 372 + bb_error_msg("%u out of %u hunk FAILED", bad_hunk_count, hunk_count);
pascal@859 373 } else {
pascal@859 374 /* It worked, we can remove the backup */
pascal@859 375 if (backup_filename) {
pascal@859 376 unlink(backup_filename);
pascal@859 377 + free(backup_filename);
pascal@859 378 }
pascal@859 379 if ((dest_cur_line == 0) || (dest_beg_line == 0)) {
pascal@859 380 /* The new patched file is empty, remove it */
pascal@859 381 xunlink(new_filename);
pascal@859 382 - if (strcmp(new_filename, original_filename) != 0)
pascal@859 383 - xunlink(original_filename);
pascal@859 384 + /* original_filename and new_filename may be the same file */
pascal@859 385 + unlink(original_filename);
pascal@859 386 }
pascal@859 387 }
pascal@859 388 - }
pascal@859 389 + } /* end of "while there are patch lines" */
pascal@859 390 +quit:
pascal@859 391
pascal@859 392 /* 0 = SUCCESS
pascal@859 393 * 1 = Some hunks failed
pascal@859 394 - * 2 = More serious problems
pascal@859 395 + * 2 = More serious problems (exited earlier)
pascal@859 396 */
pascal@859 397 return ret;
pascal@859 398 }
pascal@859 399
pascal@859 400 --- busybox-1.10.3/include/usage.h 2008-03-24 16:20:43.000000000 +0100
pascal@859 401 +++ busybox-1.10.3/include/usage.h 2008-03-24 16:22:06.000000000 +0100
pascal@859 402 @@ -2837,8 +2837,9 @@
pascal@859 403 )
pascal@859 404
pascal@859 405 #define patch_trivial_usage \
pascal@859 406 - "[-p NUM] [-i DIFF]"
pascal@859 407 + "[-R] [-p NUM] [-i DIFF]"
pascal@859 408 #define patch_full_usage \
pascal@859 409 + " -R Reverse patch\n" \
pascal@859 410 " -p NUM Strip NUM leading components from file names" \
pascal@859 411 "\n -i DIFF Read DIFF instead of stdin" \
pascal@859 412