wok annotate busybox/stuff/busybox-1.10.0-patch.u @ rev 1201

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