mksparse.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /* This file is part of GNU tar test suite
  2. Copyright (C) 2004 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or modify it
  4. under the terms of the GNU General Public License as published by the
  5. Free Software Foundation; either version 2, or (at your option) any later
  6. version.
  7. This program is distributed in the hope that it will be useful, but
  8. WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
  10. Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with this program; if not, write to the Free Software Foundation, Inc.,
  13. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  14. #ifdef HAVE_CONFIG_H
  15. # include <config.h>
  16. #endif
  17. #include <unistd.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <stdarg.h>
  21. #include <fcntl.h>
  22. #include <string.h>
  23. char *progname;
  24. char *buffer;
  25. size_t buffer_size;
  26. void
  27. die (char *fmt, ...)
  28. {
  29. va_list ap;
  30. fprintf (stderr, "%s: ", progname);
  31. va_start (ap, fmt);
  32. vfprintf (stderr, fmt, ap);
  33. va_end (ap);
  34. fprintf (stderr, "\n");
  35. }
  36. void
  37. mkhole (int fd, off_t displ)
  38. {
  39. if (displ = lseek (fd, displ, SEEK_CUR) == -1)
  40. {
  41. perror ("lseek");
  42. exit (1);
  43. }
  44. ftruncate (fd, lseek (fd, 0, SEEK_CUR));
  45. }
  46. void
  47. mksparse (int fd, off_t displ, char *marks)
  48. {
  49. int i;
  50. for (; *marks; marks++)
  51. {
  52. memset (buffer, *marks, buffer_size);
  53. if (write(fd, buffer, buffer_size) != buffer_size)
  54. {
  55. perror ("write");
  56. exit (1);
  57. }
  58. if (lseek (fd, displ, SEEK_CUR) == -1)
  59. {
  60. perror ("lseek");
  61. exit (1);
  62. }
  63. }
  64. }
  65. void
  66. usage ()
  67. {
  68. printf ("Usage: mksparse filename blocksize disp letters [disp letters...] [disp]\n");
  69. exit (1);
  70. }
  71. int
  72. xlat_suffix (off_t *vp, char *p)
  73. {
  74. if (p[1])
  75. return 1;
  76. switch (p[0])
  77. {
  78. case 'g':
  79. case 'G':
  80. *vp *= 1024;
  81. case 'm':
  82. case 'M':
  83. *vp *= 1024;
  84. case 'k':
  85. case 'K':
  86. *vp *= 1024;
  87. break;
  88. default:
  89. return 1;
  90. }
  91. return 0;
  92. }
  93. int
  94. main (int argc, char **argv)
  95. {
  96. int i;
  97. int fd;
  98. char *p;
  99. off_t n;
  100. progname = strrchr (argv[0], '/');
  101. if (progname)
  102. progname++;
  103. else
  104. progname = argv[0];
  105. if (argc < 4)
  106. usage ();
  107. fd = open (argv[1], O_CREAT|O_TRUNC|O_RDWR, 0644);
  108. if (fd < 0)
  109. die ("cannot open %s", argv[1]);
  110. n = strtoul (argv[2], &p, 0);
  111. if (n <= 0 || (*p && xlat_suffix (&n, p)))
  112. die ("Invalid buffer size: %s", argv[2]);
  113. buffer_size = n;
  114. buffer = malloc (buffer_size);
  115. if (!buffer)
  116. die ("Not enough memory");
  117. for (i = 3; i < argc; i += 2)
  118. {
  119. off_t displ;
  120. displ = strtoul (argv[i], &p, 0);
  121. if (displ < 0 || (*p && xlat_suffix (&displ, p)))
  122. die ("Invalid displacement: %s", argv[i]);
  123. if (i == argc-1)
  124. {
  125. mkhole (fd, displ);
  126. break;
  127. }
  128. else
  129. mksparse (fd, displ, argv[i+1]);
  130. }
  131. close(fd);
  132. return 0;
  133. }