cp.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. char * target_path = NULL;
  36. stat(argv[2], &statbuf);
  37. if (S_ISDIR(statbuf.st_mode)) {
  38. char *filename = strrchr(argv[1], '/');
  39. if (!filename) {
  40. filename = argv[1];
  41. }
  42. target_path = malloc((strlen(argv[2]) + strlen(filename) + 2) * sizeof(char));
  43. sprintf(target_path, "%s/%s", argv[2], filename );
  44. fout = fopen( target_path, "w" );
  45. } else {
  46. target_path = argv[2];
  47. fout = fopen( argv[2], "w" );
  48. }
  49. if (!fout) {
  50. fprintf(stderr, "%s: %s: %s\n", argv[0], target_path, strerror(errno));
  51. return 1;
  52. }
  53. size_t length;
  54. fseek(fd, 0, SEEK_END);
  55. length = ftell(fd);
  56. fseek(fd, 0, SEEK_SET);
  57. char buf[CHUNK_SIZE];
  58. while (length > CHUNK_SIZE) {
  59. fread( buf, 1, CHUNK_SIZE, fd);
  60. fwrite(buf, 1, CHUNK_SIZE, fout);
  61. length -= CHUNK_SIZE;
  62. }
  63. if (length > 0) {
  64. fread( buf, 1, length, fd);
  65. fwrite(buf, 1, length, fout);
  66. }
  67. fclose(fd);
  68. fclose(fout);
  69. if (chmod(target_path, initial_mode) < 0) {
  70. fprintf(stderr, "%s: %s: %s\n", argv[0], argv[2], strerror(errno));
  71. }
  72. return 0;
  73. }