touch.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Mini touch implementation for busybox
  4. *
  5. * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  8. */
  9. /* BB_AUDIT SUSv3 _NOT_ compliant -- options -a, -m, -r, -t not supported. */
  10. /* http://www.opengroup.org/onlinepubs/007904975/utilities/touch.html */
  11. /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
  12. *
  13. * Previous version called open() and then utime(). While this will be
  14. * be necessary to implement -r and -t, it currently only makes things bigger.
  15. * Also, exiting on a failure was a bug. All args should be processed.
  16. */
  17. #include "libbb.h"
  18. /* This is a NOFORK applet. Be very careful! */
  19. /* coreutils implements:
  20. * -a change only the access time
  21. * -c, --no-create
  22. * do not create any files
  23. * -d, --date=STRING
  24. * parse STRING and use it instead of current time
  25. * -f (ignored, BSD compat)
  26. * -m change only the modification time
  27. * -r, --reference=FILE
  28. * use this file's times instead of current time
  29. * -t STAMP
  30. * use [[CC]YY]MMDDhhmm[.ss] instead of current time
  31. * --time=WORD
  32. * change the specified time: WORD is access, atime, or use
  33. */
  34. int touch_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  35. int touch_main(int argc UNUSED_PARAM, char **argv)
  36. {
  37. #if ENABLE_DESKTOP
  38. struct utimbuf timebuf;
  39. char *reference_file = NULL;
  40. #else
  41. #define reference_file NULL
  42. #define timebuf (*(struct utimbuf*)NULL)
  43. #endif
  44. int fd;
  45. int status = EXIT_SUCCESS;
  46. int flags = getopt32(argv, "c" USE_DESKTOP("r:")
  47. /*ignored:*/ "fma"
  48. USE_DESKTOP(, &reference_file));
  49. flags &= 1; /* only -c bit is left */
  50. argv += optind;
  51. if (!*argv) {
  52. bb_show_usage();
  53. }
  54. if (reference_file) {
  55. struct stat stbuf;
  56. xstat(reference_file, &stbuf);
  57. timebuf.actime = stbuf.st_atime;
  58. timebuf.modtime = stbuf.st_mtime;
  59. }
  60. do {
  61. if (utime(*argv, reference_file ? &timebuf : NULL)) {
  62. if (errno == ENOENT) { /* no such file */
  63. if (flags) { /* creation is disabled, so ignore */
  64. continue;
  65. }
  66. /* Try to create the file. */
  67. fd = open(*argv, O_RDWR | O_CREAT,
  68. S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
  69. );
  70. if ((fd >= 0) && !close(fd)) {
  71. if (reference_file)
  72. utime(*argv, &timebuf);
  73. continue;
  74. }
  75. }
  76. status = EXIT_FAILURE;
  77. bb_simple_perror_msg(*argv);
  78. }
  79. } while (*++argv);
  80. return status;
  81. }