cp.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /* vim: tabstop=4 shiftwidth=4 noexpandtab
  2. * This file is part of ToaruOS and is released under the terms
  3. * of the NCSA / University of Illinois License - see LICENSE.md
  4. * Copyright (C) 2013 K. Lange
  5. * Copyright (C) 2013 Tyler Bindon
  6. *
  7. * cp - Copy files
  8. *
  9. * This is an incomplete implementation of `cp`. A more complete
  10. * version of recursive directory copying can be found in the
  11. * `migrate` sources, and should probably be imported here.
  12. */
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <stdio.h>
  16. #include <errno.h>
  17. #include <fcntl.h>
  18. #include <sys/stat.h>
  19. #define CHUNK_SIZE 4096
  20. int main(int argc, char ** argv) {
  21. FILE * fd;
  22. FILE * fout;
  23. if (argc < 3) {
  24. fprintf(stderr, "usage: %s [source] [destination]\n", argv[0]);
  25. return 1;
  26. }
  27. fd = fopen(argv[1], "r");
  28. if (!fd) {
  29. fprintf(stderr, "%s: %s: %s\n", argv[0], argv[1], strerror(errno));
  30. return 1;
  31. }
  32. struct stat statbuf;
  33. stat(argv[1], &statbuf);
  34. int initial_mode = statbuf.st_mode;
  35. stat(argv[2], &statbuf);
  36. if (S_ISDIR(statbuf.st_mode)) {
  37. char *filename = strrchr(argv[1], '/');
  38. if (!filename) {
  39. filename = argv[1];
  40. }
  41. char *target_path = malloc((strlen(argv[2]) + strlen(filename) + 2) * sizeof(char));
  42. sprintf(target_path, "%s/%s", argv[2], filename );
  43. fout = fopen( target_path, "w" );
  44. free(target_path);
  45. } else {
  46. fout = fopen( argv[2], "w" );
  47. }
  48. if (!fout) {
  49. fprintf(stderr, "%s: %s: %s\n", argv[0], argv[2], strerror(errno));
  50. return 1;
  51. }
  52. size_t length;
  53. fseek(fd, 0, SEEK_END);
  54. length = ftell(fd);
  55. fseek(fd, 0, SEEK_SET);
  56. char buf[CHUNK_SIZE];
  57. while (length > CHUNK_SIZE) {
  58. fread( buf, 1, CHUNK_SIZE, fd);
  59. fwrite(buf, 1, CHUNK_SIZE, fout);
  60. length -= CHUNK_SIZE;
  61. }
  62. if (length > 0) {
  63. fread( buf, 1, length, fd);
  64. fwrite(buf, 1, length, fout);
  65. }
  66. fclose(fd);
  67. fclose(fout);
  68. if (chmod(argv[2], initial_mode) < 0) {
  69. fprintf(stderr, "%s: %s: %s\n", argv[0], argv[2], strerror(errno));
  70. }
  71. return 0;
  72. }