home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 May / macformat-024.iso / Shareware City / Developers / nshellmegasource1.50 / mega src / commands / rm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-27  |  6.8 KB  |  313 lines  |  [TEXT/KAHL]

  1. /* ========== the commmand file: ==========
  2.  
  3.     rm.c
  4.     
  5.     Copyright (c) 1993,1994 Newport Software Development
  6.     
  7.     You may distribute unmodified copies of this file for
  8.     noncommercial purposes.  You may use this file as a
  9.     reference when writing your own nShell(tm) commands.
  10.     
  11.     All other rights are reserved.
  12.     
  13.    ========== the commmand file: ========== */
  14.  
  15. //
  16. // This code can build to be "rm" or "rmdir".
  17. //
  18. // To build "rm", define RM below.
  19. //
  20. // To build "rmdir", define RMDIR below.
  21. //
  22.  
  23. #define  RMDIR
  24.  
  25. #ifdef __MWERKS__            // CodeWarrior requires an A4 setup
  26. #include <A4Stuff.h>
  27. #endif
  28.  
  29. #include <script.h>
  30. #include <string.h>
  31.  
  32. #include "nshc.h"
  33.  
  34. #include "arg_utl.proto.h"
  35. #include "fss_utl.proto.h"
  36. #include "fss_utl2.proto.h"
  37. #include "nshc_utl.proto.h"
  38. #include "str_utl.proto.h"
  39.  
  40. // data definition - this struct is the root of all data
  41.  
  42. typedef struct {
  43.  
  44.     int        got_fss;        // 0 if FSSpec calls are not available
  45.     int        arg;            // position in arg list
  46.  
  47. } t_rm_data;
  48.  
  49. typedef    t_rm_data    **rm_hndl;
  50.  
  51. /* ======================================== */
  52.  
  53. // prototypes - utility
  54.  
  55. void rm_bad( t_nshc_parms *nshc_parms, int code );
  56. void rm_bad_file( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, StringPtr msg );
  57. void rm_good( t_nshc_parms *nshc_parms );
  58.  
  59. // prototypes - file routines
  60.  
  61. OSErr rm_info(const FSSpec *spec, long *theDirID, int *isDir, int *isEmpty);
  62. void  rm_one( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, t_rm_data **hData );
  63.  
  64. // prototypes - state machine
  65.  
  66. void rm_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls  );
  67. void rm_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  68. void rm_stop( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  69.  
  70. /* ======================================== */
  71.  
  72. // utility routines
  73.  
  74. /* ======================================== */
  75.  
  76. void rm_bad(  t_nshc_parms *nshc_parms, int code )
  77. {
  78.     nshc_parms->action = nsh_stop;
  79.     nshc_parms->result = code;
  80. }
  81.  
  82. void rm_bad_file(  t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, StringPtr msg )
  83. {
  84.  
  85. #if defined RM
  86.     nshc_calls->NSH_putStr_err("\prm: File access error (");
  87. #elif defined RMDIR
  88.     nshc_calls->NSH_putStr_err("\prmdir: Directory access error (");
  89. #endif
  90.  
  91.     nshc_calls->NSH_putStr_err(msg);
  92.     nshc_calls->NSH_putStr_err("\p)\r");
  93.  
  94.     nshc_parms->action = nsh_stop;
  95.     nshc_parms->result = NSHC_ERR_GENERAL;
  96. }
  97.  
  98. void rm_good(  t_nshc_parms *nshc_parms )
  99. {
  100.     nshc_parms->action = nsh_stop;
  101.     nshc_parms->result = 0;
  102. }
  103.  
  104. /* ======================================== */
  105.  
  106. // file access routines
  107.  
  108. /* ========================================== */
  109.  
  110. OSErr rm_info(const FSSpec *spec, long *theDirID, int *isDir, int *isEmpty)
  111. {
  112.     CInfoPBRec pb;
  113.     OSErr error;
  114.  
  115.     pb.hFileInfo.ioNamePtr = (StringPtr)spec->name;
  116.     pb.hFileInfo.ioVRefNum = spec->vRefNum;
  117.     pb.hFileInfo.ioDirID = spec->parID;
  118.     pb.hFileInfo.ioFDirIndex = 0;
  119.     
  120.     error = PBGetCatInfoSync(&pb);
  121.     
  122.     *theDirID = pb.hFileInfo.ioDirID;
  123.     *isDir = (pb.hFileInfo.ioFlAttrib & 0x10) != 0;
  124.     *isEmpty = pb.dirInfo.ioDrNmFls == 0;
  125.         
  126.     return (error);
  127. }
  128.  
  129. /* ======================================== */
  130.  
  131. void rm_one( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, t_rm_data **hData )
  132. {
  133.     int        result;
  134.     FSSpec    fsspec;
  135.     long    dirID;
  136.     int        isDir;
  137.     int        isEmpty;
  138.     
  139.     // =====> convert argument to fsspec
  140.     
  141.     result = arg_to_real_fss( nshc_parms, nshc_calls, (**hData).arg, &fsspec );
  142.  
  143.     (**hData).arg++;
  144.     
  145.     if (result) {
  146.         rm_bad( nshc_parms, result );
  147.         return;
  148.         }
  149.     
  150.     result = rm_info( &fsspec, &dirID, &isDir, &isEmpty );
  151.     
  152. #if defined RM
  153.  
  154.     if ( !result && isDir ) {
  155.         nshc_calls->NSH_putStr_err("\prm: Skiping directory = ");
  156.         nshc_calls->NSH_putStr_err((StringPtr)fsspec.name);
  157.         nshc_calls->NSH_putchar('\r');
  158.         return;
  159.         }
  160.  
  161. #elif defined RMDIR
  162.  
  163.     if (!result) {
  164.     
  165.         if ( !isDir ) {
  166.             nshc_calls->NSH_putStr_err("\prmdir: Skiping file = ");
  167.             nshc_calls->NSH_putStr_err((StringPtr)fsspec.name);
  168.             nshc_calls->NSH_putchar('\r');
  169.             return;
  170.             }
  171.     
  172.         if ( !isEmpty ) {
  173.             nshc_calls->NSH_putStr_err("\prmdir: Directory is not empty = ");
  174.             nshc_calls->NSH_putStr_err((StringPtr)fsspec.name);
  175.             nshc_calls->NSH_putchar('\r');
  176.             return;
  177.             }
  178.         
  179.         }
  180.  
  181. #endif
  182.             
  183.     if ( result == fnfErr ) {
  184.  
  185.         #if defined RM
  186.         nshc_calls->NSH_putStr_err("\prm: File not found = ");
  187.         #elif defined RMDIR
  188.         nshc_calls->NSH_putStr_err("\prmdir: Directory not found = ");
  189.         #endif
  190.  
  191.         nshc_calls->NSH_putStr_err((StringPtr)fsspec.name);
  192.         nshc_calls->NSH_putchar('\r');
  193.         return;
  194.         }
  195.             
  196.     if ( result ) {
  197.         rm_bad_file( nshc_parms, nshc_calls, (StringPtr)fsspec.name );
  198.         nshc_calls->NSH_printf( "error = %d\r", result );
  199.         return;
  200.         }
  201.             
  202.     // =====> delete the file or directory
  203.         
  204.     result = fss_Delete((**hData).got_fss, &fsspec);
  205.     
  206.     if ( result ) {
  207.         rm_bad_file( nshc_parms, nshc_calls, (StringPtr)fsspec.name );
  208.         return;
  209.         }
  210.  
  211.     result = fss_wake_parent( &fsspec );
  212.  
  213.     if (result)
  214.         nshc_calls->NSH_putStr_err( "\pmv: Warning - could update finder info.\r" );
  215. }
  216.  
  217. /* ======================================== */
  218.  
  219. // state machine - core routines
  220.  
  221. /* ======================================== */
  222.  
  223. void rm_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls  )
  224. {
  225.     rm_hndl    hData;    // handle to hold our data
  226.     
  227.     if (nshc_parms->argc < 2) {
  228.     
  229.         #if defined RM
  230.         nshc_calls->NSH_putStr_err( "\pUsage: rm file [file...]\r" );
  231.         #elif defined RMDIR
  232.         nshc_calls->NSH_putStr_err( "\pUsage: rmdir dir [dir...]\r" );
  233.         #endif
  234.  
  235.         rm_bad( nshc_parms, NSHC_ERR_PARMS );
  236.         return;
  237.         }
  238.         
  239.     nshc_parms->action = nsh_continue;
  240.  
  241.     hData = (rm_hndl)NewHandleClear(sizeof(t_rm_data));
  242.     
  243.     if (hData) {
  244.         (**hData).arg = 1;                    // start at the arg = 1 position
  245.         (**hData).got_fss = fss_test();        // test if we can use FSSpec calls
  246.         nshc_parms->data = (Handle)hData;
  247.         }
  248.     else {
  249.         nshc_calls->NSH_putStr_err( "\prm: Could not allocate storage.\r" );
  250.         rm_bad( nshc_parms, NSHC_ERR_MEMORY );
  251.         }
  252. }
  253.  
  254. /* ======================================== */
  255.  
  256. void rm_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  257. {
  258.     int        i;
  259.     rm_hndl    hData;
  260.     
  261.     if (hData = (rm_hndl)nshc_parms->data) {
  262.  
  263.         if ((**hData).arg >= nshc_parms->argc)
  264.             rm_good( nshc_parms );
  265.         else
  266.             rm_one( nshc_parms, nshc_calls, hData );
  267.  
  268.         }
  269. }
  270.  
  271. /* ======================================== */
  272.  
  273. void rm_stop( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  274. {
  275.     rm_hndl    hData;
  276.     
  277.     if (hData = (rm_hndl)nshc_parms->data)
  278.         DisposeHandle(nshc_parms->data);
  279.         
  280.     nshc_parms->action = nsh_idle;
  281. }
  282.  
  283. /* ======================================== */
  284.  
  285. void main(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls)
  286. {
  287. #ifdef __MWERKS__
  288.     long oldA4  = SetCurrentA4();
  289. #endif
  290.     
  291.     if ( !nshc_bad_version( nshc_parms, nshc_calls, NSHC_VERSION ) ) {
  292.     
  293.         switch (nshc_parms->action) {
  294.             case nsh_start:
  295.                 rm_start(nshc_parms, nshc_calls);
  296.                 break;
  297.             case nsh_continue:
  298.                 rm_continue(nshc_parms, nshc_calls);
  299.                 break;
  300.             case nsh_stop:
  301.                 rm_stop(nshc_parms, nshc_calls);
  302.                 break;
  303.             }
  304.     
  305.         }
  306.     
  307. #ifdef __MWERKS__
  308.     SetA4(oldA4);
  309. #endif
  310. }
  311.  
  312. /* ======================================== */
  313.