home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser 2002 January / STC_CD_01_2002.iso / UTILS / PACKIT / PACKIT.C next >
C/C++ Source or Header  |  2000-05-04  |  8KB  |  340 lines

  1. /*
  2. ** PackIt - a simple shell for tar, zip and lha
  3. **
  4. ** This piece of useful, but badly written software is published
  5. ** without any license whatsoever. Do what you like with it.
  6. **
  7. ** Sorry for the Norwegian variable-names, but I didn't intend to release
  8. ** it when I started it. It started out as a tiny hack with a very
  9. ** specific purpose and evolved into a slightly bigger hack which
  10. ** might be of use for others. It's inspired by Kellis' tarit, which
  11. ** was a bit limited to my taste.
  12. **
  13. ** To use it simply drag one or more folders or files to PackIt, or put
  14. ** it in Thing's SendTo-group. A fileselector will now popup and tell you
  15. ** what to do. If you've only selected tar, tar.gz, tgz, zip, lha or lzh
  16. ** archives you can now select which folder to unpack these to. Otherwise
  17. ** you'll have to select which archive to store the files/folders in.
  18. ** PackIt will run the appropriate packer depending on the extension of
  19. ** this archive.
  20. **
  21. ** PackIt will most likely only work under MiNT, and the following files
  22. ** should be present on your system:
  23. ** /bin/tar
  24. ** /bin/gzip
  25. ** /bin/lha
  26. ** /bin/zip
  27. ** /bin/unzip
  28. ** /bin/sh (atleast I think MiNT-libs implementation of system() requires
  29. **          this).
  30. **
  31. ** NB! As I said, this hack is badly written, I wouldn't have written it
  32. ** like this if I knew that it would turn out this useful. Don't follow
  33. ** my example, spend some time digging out documentation instead of
  34. ** hacking together poor replacements for stdlib-stuff...
  35. **
  36. ** Suggestions for improvement:
  37. ** 1. Check whether an archive exists or not, and ask the user if [s]he
  38. **    wants to overwrite or add to it.
  39. ** 2. Modify it to use Pexec() instead of system(), this should make it
  40. **    a bit more efficient and TOS/MagiC-friendly.
  41. ** 3. Clean it up and integrate it in Thing :-)
  42. **
  43. ** ╜ Jo Even Skarstein, 2/5-2000
  44. **   joska@nvg.org
  45. **   http://home.nvg.org/~joska/
  46. **   http://atari.nvg.org/
  47. */
  48.  
  49. #ifndef TRUE
  50. #define FALSE 0
  51. #define TRUE 1
  52. #endif
  53.  
  54. #include <stdio.h>
  55. #include <gem.h>
  56. #include <mintbind.h>
  57.  
  58. char *dos2unix(char *inn);
  59. int sjekkFilSuffix(char *filnamn, char *suffix, int casesensitive);
  60. int cwd(char *dir);
  61.  
  62. char pack_arg[5000], pack_cmd[5000], archive[256], sti[256], fil[256], cd[256];
  63.  
  64. /*
  65. ** main
  66. */
  67. int main(int argc, char **argv)
  68. {
  69.     int err = 0, ok = FALSE;
  70.     char tmp[256];
  71.  
  72.     Pdomain(1);
  73.     
  74.     /*
  75.     ** Don't do anything if there's no arguments
  76.     */
  77.     if (argc > 1)
  78.     {
  79.         int i, cut, archives_only = TRUE;
  80.  
  81.         /*
  82.         ** This is an AES-application
  83.         */
  84.         if (appl_init() == -1)
  85.         {
  86.             printf("appl_init() failed!");
  87.             exit();
  88.         }
  89.  
  90.         /*
  91.         ** First we find the path to the fils(s)/folder(s).
  92.         ** NB! This is simply done by extracting the path to the *first*
  93.         ** file or folder, so dragging files/folders from different
  94.         ** directories won't work. Feel free to fix this. It's not trivial
  95.         ** though, and a bit out of scope for this small hack.
  96.         */
  97.         strcpy(tmp, dos2unix(argv[1]));
  98.         cut = strlen(tmp) - 1;
  99.         if (tmp[cut] == '/') cut--;
  100.         for (; tmp[cut] != '/'; cut--); cut++;
  101.         strcpy(cd, tmp);
  102.         cd[cut] = '\0';
  103.  
  104.         /*
  105.         ** Build a string with all files/folders without their path.
  106.         */
  107.         pack_arg[0] = '\0';
  108.         for (i = 1; i < argc; i++)
  109.         {
  110.             /*
  111.             ** Now that we're stepping through argv anyway we check if all
  112.             ** files are archives.
  113.             */
  114.             if (!sjekkFilSuffix(argv[i], "tar", FALSE) &&
  115.                  !sjekkFilSuffix(argv[i], "tar.gz", FALSE) &&
  116.                  !sjekkFilSuffix(argv[i], "tgz", FALSE) &&
  117.                  !sjekkFilSuffix(argv[i], "zip", FALSE) &&
  118.                  !sjekkFilSuffix(argv[i], "lha", FALSE) &&
  119.                  !sjekkFilSuffix(argv[i], "lzh", FALSE))
  120.                 {
  121.                     archives_only = FALSE;
  122.                 }
  123.  
  124.             sprintf(tmp, " '%s'", dos2unix(&(argv[i])[cut]));
  125.             strcat(pack_arg, tmp);
  126.         }
  127.  
  128.         /*
  129.         ** Fileselector. Needs TOS 1.04 or better.
  130.         */
  131.         strcpy(sti, "u:\\tmp\\*.*");
  132.         strcpy(fil, "");
  133.  
  134.         if (archives_only)
  135.         {
  136.             fsel_exinput(sti, fil, &ok, "Select folder to unpack to.");
  137.         }
  138.         else
  139.         {
  140.             fsel_exinput(sti, fil, &ok, "Select archive.");
  141.         }
  142.  
  143.         if (ok)
  144.         {
  145.             int i;
  146.             
  147.             /*
  148.             ** Remove the mask from the path returned by the
  149.             ** fileselector.
  150.             */
  151.             for (i = strlen(sti); sti[i] != '\\'; i--);
  152.             sti[i] = '\0';
  153.  
  154.             if (archives_only)
  155.             {
  156.                 /*
  157.                 ** Unpack all archives to this path.
  158.                 */
  159.                 char *arc;
  160.  
  161.                 /*
  162.                 ** Set current path
  163.                 */
  164.                 cwd(dos2unix(sti));
  165.  
  166.                 /*
  167.                 ** Step through the list of archives.
  168.                 */
  169.                 for (i = 1; i < argc; i++)
  170.                 {
  171.                     arc = argv[i];
  172.                     if (sjekkFilSuffix(arc, "tar", FALSE))
  173.                         sprintf(pack_cmd, "/bin/tar -x --force-local -f %s", arc);
  174.  
  175.                     if (sjekkFilSuffix(arc, "tar.gz", FALSE) || sjekkFilSuffix(archive, "tgz", FALSE))
  176.                         sprintf(pack_cmd, "/bin/tar -x --force-local -z -f %s", arc);
  177.  
  178.                     if (sjekkFilSuffix(arc, "zip", FALSE))
  179.                         sprintf(pack_cmd, "/bin/unzip -qq %s", arc);
  180.  
  181.                     if (sjekkFilSuffix(arc, "lha", FALSE) || sjekkFilSuffix(arc, "lzh", FALSE))
  182.                         sprintf(pack_cmd, "/bin/lha xq %s", arc);
  183.  
  184.                     system(pack_cmd);
  185.                 }                
  186.             }
  187.             else
  188.             {
  189.                 /*
  190.                 ** Pack files/folders to the selected archive.
  191.                 */
  192.  
  193.                 /*
  194.                 ** Set current path, build a complete path/filename for the archive.
  195.                 */
  196.                 cwd(cd);
  197.                 sprintf(archive, "%s/%s", dos2unix(sti), fil);
  198.  
  199.                 /*
  200.                 ** Build argument strings and call the appropriate packers
  201.                 */
  202.                 if (sjekkFilSuffix(fil, "tar", FALSE))
  203.                 {
  204.                     sprintf(pack_cmd, "/bin/tar -c --force-local -f %s %s", archive, pack_arg);
  205.                     err = system(pack_cmd);
  206.                 }
  207.  
  208.                 if (sjekkFilSuffix(fil, "tar.gz", FALSE) || sjekkFilSuffix(archive, "tgz", FALSE))
  209.                 {
  210.                     sprintf(pack_cmd, "/bin/tar -c -z --force-local -f %s %s", archive, pack_arg);
  211.                     err = system(pack_cmd);
  212.                 }
  213.  
  214.                 if (sjekkFilSuffix(fil, "zip", FALSE))
  215.                 {
  216.                     sprintf(pack_cmd, "/bin/zip -q -r %s %s", archive, pack_arg);
  217.                     err = system(pack_cmd);
  218.                 }
  219.  
  220.                 if (sjekkFilSuffix(fil, "lha", FALSE) || sjekkFilSuffix(archive, "lzh", FALSE))
  221.                 {
  222.                     sprintf(pack_cmd, "/bin/lha aq %s %s", archive, pack_arg);
  223.                     err = system(pack_cmd);
  224.                 }
  225.             }
  226.         }
  227.  
  228.         appl_exit();
  229.     }
  230.  
  231.     return err;
  232. }
  233.  
  234. /*
  235. ** Converts DOS-paths to unix-paths. Pathetic implementation, but
  236. ** it works.
  237. */
  238. char *dos2unix(char *inn)
  239. {
  240.     int t;
  241.  
  242.     for (t = 0; inn[t] != '\0'; t++)
  243.     {
  244.         if (inn[t] == '\\')
  245.         {
  246.             inn[t] = '/';
  247.         }
  248.     }
  249.     
  250.     return inn;
  251. }
  252.  
  253. /*
  254. ** Check if the file 'filnamn' has the extension 'suffix'.
  255. */
  256. int sjekkFilSuffix(char *filnamn, char *suffix, int casesensitive)
  257. {
  258.     long lFil, lSuf;
  259.     char fSuffix[255];
  260.     
  261.     lFil = strlen(filnamn);
  262.     lSuf = strlen(suffix);
  263.     if (lSuf >= lFil)
  264.     {
  265.         return FALSE;
  266.     }
  267.  
  268.     strcpy(fSuffix, &filnamn[lFil - lSuf]);
  269.     switch (casesensitive)
  270.     {
  271.         case TRUE:
  272.             return !strcmp(fSuffix, suffix);
  273.         case FALSE:
  274.             return !strcmpi(fSuffix, suffix);
  275.     }
  276.  
  277.     return FALSE;
  278. }
  279.  
  280.  
  281. /*
  282. ** Set current directory. If this directory doesn't exist, attempt
  283. ** to create it.
  284. */
  285. int cwd(char *dir)
  286. {
  287.     long int d;
  288.     char path[256], drive;
  289.  
  290.     strcpy(path, dir);
  291.     for (d = 0; path[d] != '\0'; d++)
  292.     {
  293.         if (path[d] == '/') path[d] = '\\';
  294.     }
  295.  
  296.     if (strlen(path) < 3)
  297.     {
  298.         return FALSE;
  299.     }
  300.  
  301.     if (strlen(path) > 3 && path[strlen(path) - 1] == '\\')
  302.     {
  303.         path[strlen(path) - 1] = '\0';
  304.     }
  305.     drive = path[0];
  306.     
  307.     if (drive >= 'a' && drive <= 'z')
  308.     {
  309.         d = (int)(drive - 'a');
  310.     }
  311.     else
  312.     {
  313.         d = (int)(drive - 'A');
  314.     }
  315.  
  316.     Dsetdrv(d);
  317.     
  318.     if (Dsetpath(&path[2]))
  319.     {
  320.         /*
  321.         ** Directory doesn't exist, attempt to create it.
  322.         */
  323.         if (strlen(&path[2]) > 1)
  324.         {
  325.             if (Dcreate(path))
  326.             {
  327.                 /*
  328.                 ** Failed.
  329.                 */
  330.                 return FALSE;
  331.             }
  332.             else
  333.             {
  334.                 Dsetpath(&path[2]);
  335.             }
  336.         }
  337.     }
  338.  
  339.     return TRUE;
  340. }