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

  1. /* ========== the commmand file: ==========
  2.  
  3.     chattr.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. #ifdef __MWERKS__            // CodeWarrior requires an A4 setup
  16. #include <A4Stuff.h>
  17. #endif
  18.  
  19. #include <script.h>
  20. #include <string.h>
  21.  
  22. #include "nshc.h"
  23.  
  24. #include "arg_utl.proto.h"
  25. #include "fss_utl.proto.h"
  26. #include "nshc_utl.proto.h"
  27. #include "str_utl.proto.h"
  28.  
  29. // data definition - this struct is the root of all data
  30.  
  31. typedef struct {
  32.  
  33.     int        got_fss;        // 0 if FSSpec calls are not available
  34.     int        arg;            // position in arg list
  35.     
  36.     int        got_one;        // 0 until header is printed
  37.     
  38.     int        change_type;    // 0 if none, or arg pos of "-t"
  39.     OSType    new_type;
  40.     
  41.     int        change_creator;    // 0 if none, or arg pos of "-c"
  42.     OSType    new_creator;
  43.  
  44. } t_chattr_data;
  45.  
  46. typedef    t_chattr_data    **chattr_hndl;
  47.  
  48. /* ======================================== */
  49.  
  50. // prototypes - utility
  51.  
  52. int  chattr_get_OSType(t_nshc_parms *nshc_parms, int arg, OSType *selector);
  53. void chattr_bad( t_nshc_parms *nshc_parms, int code );
  54. void chattr_bad_file( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, StringPtr msg );
  55. void chattr_good( t_nshc_parms *nshc_parms );
  56.  
  57. // prototypes - file routines
  58.  
  59. void  chattr_one( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, t_chattr_data **hData );
  60.  
  61. // prototypes - state machine
  62.  
  63. void chattr_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls  );
  64. void chattr_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  65. void chattr_stop( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  66.  
  67. /* ======================================== */
  68.  
  69. // utility routines
  70.  
  71. int chattr_get_OSType(t_nshc_parms *nshc_parms, int arg, OSType *os_type)
  72. {
  73.     char    c;
  74.     char    *p;
  75.     int        i;
  76.     int        success;
  77.     
  78.     if (arg >= nshc_parms->argc)
  79.         return(0);
  80.     
  81.     success = 1;
  82.     *os_type = 0;
  83.     
  84.     p = &nshc_parms->arg_buf[ nshc_parms->argv[ arg ] ];
  85.     
  86.     for (i = 0 ; i < 4 ; i++ )
  87.         if ( c = *p++ ) {
  88.             *os_type = *os_type << 8;
  89.             *os_type = *os_type + c;
  90.             }
  91.         else
  92.             success = 0;
  93.             
  94.     if (*p) success = 0;
  95.     
  96.     return(success);
  97. }
  98.     
  99. /* ======================================== */
  100.  
  101. void chattr_bad(  t_nshc_parms *nshc_parms, int code )
  102. {
  103.     nshc_parms->action = nsh_stop;
  104.     nshc_parms->result = code;
  105. }
  106.     
  107. /* ======================================== */
  108.  
  109. void chattr_bad_file(  t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, StringPtr msg )
  110. {
  111.  
  112.     nshc_calls->NSH_putStr_err("\pchattr: File access error (");
  113.     nshc_calls->NSH_putStr_err(msg);
  114.     nshc_calls->NSH_putStr_err("\p)\r");
  115.  
  116.     nshc_parms->action = nsh_stop;
  117.     nshc_parms->result = NSHC_ERR_GENERAL;
  118. }
  119.     
  120. /* ======================================== */
  121.  
  122. void chattr_good(  t_nshc_parms *nshc_parms )
  123. {
  124.     nshc_parms->action = nsh_stop;
  125.     nshc_parms->result = 0;
  126. }
  127.  
  128. /* ======================================== */
  129.  
  130. // file access routines
  131.  
  132. /* ======================================== */
  133.  
  134. void chattr_one( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, t_chattr_data **hData )
  135. {
  136.     int        result;
  137.     FSSpec    fsspec;
  138.     FInfo    fndrInfo;
  139.     int        write;
  140.     
  141.     // =====> convert argument to fsspec
  142.     
  143.     result = arg_to_fss( nshc_parms, nshc_calls, (**hData).arg, &fsspec );
  144.  
  145.     (**hData).arg++;
  146.     
  147.     if (result) {
  148.         chattr_bad( nshc_parms, result );
  149.         return;
  150.         }
  151.     
  152.     result = fss_GetFInfo((**hData).got_fss, &fsspec, &fndrInfo);
  153.                 
  154.     if (result == fnfErr) {
  155.         nshc_calls->NSH_putStr_err("\pchattr: Not a file (");
  156.         nshc_calls->NSH_putStr_err((StringPtr)fsspec.name);
  157.         nshc_calls->NSH_putStr_err("\p)\r");
  158.         return;
  159.         }
  160.     
  161.     if (!result) {
  162.     
  163.         write = 0;
  164.     
  165.         if ( (**hData).change_type ) {
  166.             write = 1;
  167.             fndrInfo.fdType = (**hData).new_type;
  168.             }
  169.             
  170.         if ( (**hData).change_creator ) {
  171.             write = 1;
  172.             fndrInfo.fdCreator = (**hData).new_creator;
  173.             }
  174.             
  175.         if (write) {
  176.             result = fss_SetFInfo((**hData).got_fss, &fsspec, &fndrInfo);
  177.             if (!result)
  178.                 result = fss_wake_parent( &fsspec );
  179.             }
  180.             
  181.         if (!(**hData).got_one) {
  182.             nshc_calls->NSH_puts("  Crea   Type  Name\r");
  183.             nshc_calls->NSH_puts(" ------ ------ ----\r");
  184.             (**hData).got_one = 1;
  185.             }
  186.                 
  187.         nshc_calls->NSH_printf( " '%.4s' '%.4s' ", &fndrInfo.fdCreator, &fndrInfo.fdType );
  188.         nshc_calls->NSH_putStr( (StringPtr)fsspec.name );
  189.         nshc_calls->NSH_putchar( '\r' );
  190.         
  191.         }
  192.     
  193.     if ( result )
  194.         chattr_bad_file( nshc_parms, nshc_calls, (StringPtr)fsspec.name );
  195. }
  196.  
  197. /* ======================================== */
  198.  
  199. // state machine - core routines
  200.  
  201. /* ======================================== */
  202.  
  203. void chattr_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls  )
  204. {
  205.     int            arg;
  206.     OSType        os_type;
  207.     chattr_hndl    hData;    // handle to hold our data
  208.     
  209.     if (nshc_parms->argc < 2) {
  210.         nshc_calls->NSH_putStr_err( "\pUsage: chattr file [file...] [-t type] [-c crea]\r" );
  211.         chattr_bad( nshc_parms, NSHC_ERR_PARMS );
  212.         return;
  213.         }
  214.         
  215.     nshc_parms->action = nsh_continue;
  216.  
  217.     hData = (chattr_hndl)NewHandleClear(sizeof(t_chattr_data));
  218.     
  219.     if (hData) {
  220.     
  221.         (**hData).arg = 1;                    // start at the arg = 1 position
  222.         (**hData).got_fss = fss_test();        // test if we can use FSSpec calls
  223.         
  224.         // test if we are doing a type change
  225.         
  226.         if (arg = nshc_got_option( nshc_parms, 't' ))
  227.             if (chattr_get_OSType( nshc_parms, arg+1, &os_type)) {
  228.                 (**hData).change_type = arg;
  229.                 (**hData).new_type = os_type;
  230.                 }
  231.             else {
  232.                 nshc_calls->NSH_putStr_err( "\pchattr: Bad OSType given for type.\r" );
  233.                 chattr_bad( nshc_parms, NSHC_ERR_PARMS );
  234.                 }
  235.             
  236.         // test if we are doing a creator change
  237.         
  238.         if (arg = nshc_got_option( nshc_parms, 'c' ))
  239.             if (chattr_get_OSType( nshc_parms, arg+1, &os_type)) {
  240.                 (**hData).change_creator = arg;
  241.                 (**hData).new_creator = os_type;
  242.                 }
  243.             else {
  244.                 nshc_calls->NSH_putStr_err( "\pchattr: Bad OSType given for creator.\r" );
  245.                 chattr_bad( nshc_parms, NSHC_ERR_PARMS );
  246.                 }
  247.             
  248.         nshc_parms->data = (Handle)hData;
  249.         }
  250.     else {
  251.         nshc_calls->NSH_putStr_err( "\pchattr: Could not allocate storage.\r" );
  252.         chattr_bad( nshc_parms, NSHC_ERR_MEMORY );
  253.         }
  254. }
  255.  
  256. /* ======================================== */
  257.  
  258. void chattr_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  259. {
  260.     int        i;
  261.     int        arg;
  262.     chattr_hndl    hData;
  263.     
  264.     if (hData = (chattr_hndl)nshc_parms->data) {
  265.     
  266.         arg = (**hData).arg;
  267.         
  268.         while ( ( arg == (**hData).change_type ) || ( arg == (**hData).change_creator ) ) {
  269.             arg += 2;
  270.             (**hData).arg = arg;
  271.             }
  272.  
  273.         if (arg >= nshc_parms->argc)
  274.             chattr_good( nshc_parms );
  275.         else
  276.             chattr_one( nshc_parms, nshc_calls, hData );
  277.  
  278.         }
  279. }
  280.  
  281. /* ======================================== */
  282.  
  283. void chattr_stop( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  284. {
  285.     chattr_hndl    hData;
  286.     
  287.     if (hData = (chattr_hndl)nshc_parms->data)
  288.         DisposeHandle(nshc_parms->data);
  289.         
  290.     nshc_parms->action = nsh_idle;
  291. }
  292.  
  293. /* ======================================== */
  294.  
  295. void main(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls)
  296. {    
  297. #ifdef __MWERKS__
  298.     long oldA4  = SetCurrentA4();
  299. #endif
  300.  
  301.     if ( !nshc_bad_version( nshc_parms, nshc_calls, NSHC_VERSION ) ) {
  302.     
  303.         switch (nshc_parms->action) {
  304.             case nsh_start:
  305.                 chattr_start(nshc_parms, nshc_calls);
  306.                 break;
  307.             case nsh_continue:
  308.                 chattr_continue(nshc_parms, nshc_calls);
  309.                 break;
  310.             case nsh_stop:
  311.                 chattr_stop(nshc_parms, nshc_calls);
  312.                 break;
  313.             }
  314.         
  315.         }
  316.     
  317. #ifdef __MWERKS__
  318.     SetA4(oldA4);
  319. #endif
  320. }
  321.  
  322. /* ======================================== */
  323.