home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Modules / Doslibmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  20.3 KB  |  909 lines

  1.  
  2. /********************************************************************
  3.  
  4.     Lowlevel Amiga dos.library module.
  5.  
  6. -----------------------------------------------
  7.     ©Irmen de Jong.
  8.  
  9.     History:
  10.  
  11.      9-jun-96   Created.
  12.     13-jun-96   Added WaitSignal().
  13.     17-nov-96   Fixed empty template handling.
  14.     31-dec-96   Changed CheckSignal to look like WaitSignal.
  15.     18-jan-98   Updated for Python 1.5
  16.     27-sep-98    Added some extra functions.
  17.     12-nov-98    Renamed `doslib' to `Doslib'
  18.     1-oct-2000    Added raw console functions
  19.  
  20. Module members:
  21.  
  22.     error       -- Exeption string object.  ('Doslib.error')
  23.     ReadArgs    -- dos.library/ReadArgs function.
  24.                    result=Doslib.ReadArgs(template,args,types)
  25.  
  26.     WaitSignal  -- generic Wait() function, like select. Waits for certain
  27.                    signals to occur.
  28.                    (sigs,objlist) = WaitSignal(args)
  29.                    args = integer, object, or list of ints/objects.
  30.                    integers are sigmask values. Objects must have 'signal'
  31.                    attribute to get this value.
  32.  
  33.     CheckSignal -- Like Wait() but DOES NOT WAIT FOR THE SIGNALS:
  34.                    merely checks if certain signals are set.
  35.  
  36.     CompareDates, DateStamp, DateToStr, StrToDate, Fault,
  37.     IoErr, SetIoErr, IsFileSystem, Relabel, SetProtection,
  38.     SetComment, Examine, Inhibit, SetFileDate, SetOwner, Info,
  39.     GetProgramDir, GetProgramName: 
  40.         just like the original dos.library calls.
  41.  
  42.     DS2time     -- convert DateStamp tuple to time() value (see time module)
  43.     time2DS     -- convert time() value to DateStamp tuple (see time module)
  44.  
  45.  
  46. **************************************************************************/
  47.  
  48. #include <stdlib.h>
  49. #include <exec/types.h>
  50. #include <exec/memory.h>
  51. #include <dos/dos.h>
  52. #include <dos/datetime.h>
  53. #include <dos/rdargs.h>
  54. #include <proto/dos.h>
  55. #include <proto/exec.h>
  56. #include "Python.h"
  57.  
  58.  
  59. static PyObject *error;    // Exception
  60.  
  61.  
  62. /* Convenience; sets error with IoError() string, return NULL */
  63. /* If ok, return Py_NONE */
  64. static PyObject *check_ok(BOOL ok)
  65. {
  66.     char buf[100];
  67.     if(ok)
  68.     {
  69.         Py_INCREF(Py_None);
  70.         return Py_None;
  71.     }
  72.  
  73.     Fault(IoErr(),NULL,buf,100);
  74.     PyErr_SetString(error,buf);
  75.     return NULL;
  76. }
  77.  
  78.  
  79. /************** MODULE FUNCTIONS *******************/
  80.  
  81. static PyObject *
  82. Doslib_ReadArgs(PyObject *self, PyObject *arg)
  83. {
  84.     char *template;
  85.     char *args;
  86.     PyObject *types;        // the keywords & their types (tuple of tuples)
  87.  
  88.     PyObject *result=NULL;
  89.  
  90.     LONG *argarray;
  91.     int num_args;
  92.     BOOL free_args=FALSE;
  93.     
  94.     if (!PyArg_ParseTuple(arg, "ssO!", &template, &args,
  95.         &PyTuple_Type,&types))
  96.         return NULL;
  97.  
  98.     if(PyTuple_Size(types)>0 || strlen(template)>0)
  99.     {
  100.         /* check argument count */
  101.         char *t=template;
  102.         num_args=1;
  103.         while(*t)
  104.         {
  105.             if(*t++ == ',') num_args++;
  106.         }
  107.         if(num_args!=PyTuple_Size(types))
  108.         {
  109.             PyErr_SetString(PyExc_ValueError,"types length does not match template");
  110.             return NULL;
  111.         }
  112.     }
  113.     else
  114.     {
  115.         /* template is empty string; no arguments expected */
  116.         if(strlen(stpblk(args))>0)
  117.         {
  118.             SetIoErr(ERROR_TOO_MANY_ARGS);
  119.             return check_ok(FALSE);
  120.         }
  121.         return PyDict_New();        // empty result dictionary
  122.     }
  123.  
  124.     if(argarray=calloc(sizeof(LONG),num_args))
  125.     {
  126.         struct RDArgs *rdargs;
  127.         int arglen=strlen(args);
  128.  
  129.         if((arglen==0) || (args[arglen-1]!='\n'))
  130.         {
  131.             char *t = malloc(arglen+2);
  132.             if(t)
  133.             {
  134.                 strcpy(t,args); t[arglen++]='\n'; t[arglen]=0;  // add \n !!!
  135.                 args=t; free_args=TRUE;
  136.             }
  137.             else
  138.             {
  139.                 free(argarray);
  140.                 return PyErr_NoMemory();
  141.             }
  142.         }
  143.  
  144.         if(rdargs = AllocDosObject(DOS_RDARGS, NULL))
  145.         {
  146.             rdargs->RDA_Flags = RDAF_NOPROMPT;
  147.             rdargs->RDA_Source.CS_Buffer = args;
  148.             rdargs->RDA_Source.CS_Length = arglen;
  149.             rdargs->RDA_Source.CS_CurChr = 0;
  150.             rdargs->RDA_DAList = NULL;
  151.             rdargs->RDA_Buffer = NULL;
  152.  
  153.             if( !ReadArgs(template, argarray, rdargs) )
  154.             {
  155.                 (void)check_ok(FALSE);
  156.             }
  157.             else
  158.             {
  159.                 if(result=PyDict_New())
  160.                 {
  161.                     /************
  162.                     Traverse the types tuple and for each argument,
  163.                     extract it's value. types consists of tuples (k,t) where:
  164.                     k=keyword;
  165.                     t=the keyword's type:
  166.                         'X'     - string
  167.                         'S','T' - bool (integer)   !!! T not yet supported 
  168.                         'N'     - integer
  169.                         'A'     - array of strings
  170.                         'I'     - array of ints
  171.                     ***********/
  172.  
  173.                     PyObject *tup, *val;
  174.                     BOOL result_ok=TRUE;
  175.                     int cnt=0;
  176.                     while (result_ok && (tup=PyTuple_GetItem(types, cnt)))
  177.                     {
  178.                         PyObject *keyword, *type;
  179.                         char *type_c;
  180.  
  181.                         if(PyTuple_Size(tup)!=2)
  182.                         {
  183.                             PyErr_SetString(PyExc_ValueError,"types tuple invalid");
  184.                             result_ok=FALSE; break;
  185.                         }
  186.  
  187.                         keyword=PyTuple_GetItem(tup,0);
  188.                         type=PyTuple_GetItem(tup,1);
  189.  
  190.                         result_ok=FALSE;
  191.                         type_c=PyString_AsString(type);
  192.                         if(type_c==NULL)
  193.                         {
  194.                             result_ok=FALSE; break; /* no string!? */
  195.                         }
  196.  
  197.                         switch (type_c[0]) {
  198.                         case 'S':       // boolean switch
  199.                             if(val=PyInt_FromLong(argarray[cnt]))
  200.                             {
  201.                                 result_ok=(0==PyDict_SetItem(result,keyword,val));
  202.                                 Py_DECREF(val);
  203.                             }
  204.                             break;
  205.                         case 'N':       // number
  206.                             if(argarray[cnt])
  207.                             {
  208.                                 if(val=PyInt_FromLong(*(LONG*)argarray[cnt]))
  209.                                 {
  210.                                     result_ok=(0==PyDict_SetItem(result,keyword,val));
  211.                                     Py_DECREF(val);
  212.                                 }
  213.                             }
  214.                             else result_ok=(0==PyDict_SetItem(result,keyword,Py_None));
  215.                             break;
  216.                         case 'X':       // string
  217.                             if(argarray[cnt])
  218.                             {
  219.                                 if(val=PyString_FromString((STRPTR)argarray[cnt]))
  220.                                 {
  221.                                     result_ok=(0==PyDict_SetItem(result,keyword,val));
  222.                                     Py_DECREF(val);
  223.                                 }
  224.                             }
  225.                             else result_ok=(0==PyDict_SetItem(result,keyword,Py_None));
  226.                             break;
  227.                         case 'A':       // array of strings
  228.                         case 'I':       // array of numbers
  229.                             if(val=PyList_New(0))
  230.                             {
  231.                                 if(argarray[cnt])
  232.                                 {
  233.                                     if(type_c[0]=='A')
  234.                                     {
  235.                                         char **str = (char**)argarray[cnt];
  236.                                         PyObject *so;
  237.                                         /* build the string list */
  238.                                         while(*str)
  239.                                         {
  240.                                             if(so=PyString_FromString(*str))
  241.                                             {
  242.                                                 if(!(result_ok=(0==PyList_Append(val,so))))
  243.                                                     break;
  244.                                                 Py_DECREF(so);
  245.                                             }
  246.                                             else break;
  247.                                             str++;
  248.                                         }
  249.                                     }
  250.                                     else /* array of numbers */
  251.                                     {
  252.                                         int **ia = (int**)argarray[cnt];
  253.                                         PyObject *io;
  254.                                         /* build the integer list */
  255.                                         while(*ia)
  256.                                         {
  257.                                             if(io=PyInt_FromLong(**ia))
  258.                                             {
  259.                                                 if(!(result_ok=(0==PyList_Append(val,io))))
  260.                                                     break;
  261.                                                 Py_DECREF(io);
  262.                                             }
  263.                                             else break;
  264.                                             ia++;
  265.                                         }
  266.                                     }
  267.                                     result_ok=result_ok&&(0==PyDict_SetItem(result,keyword,val));
  268.                                 }
  269.                                 else
  270.                                 {
  271.                                     // insert the empty list.
  272.                                     result_ok=(0==PyDict_SetItem(result,keyword,val));
  273.                                 }
  274.                                 Py_DECREF(val);
  275.                             }
  276.                             break;
  277.                         default:
  278.                             PyErr_SetString(PyExc_ValueError,"illegal arg type");
  279.                             break;
  280.                         }
  281.                         cnt++;
  282.                     }
  283.                     if(!result_ok)
  284.                     {
  285.                         Py_DECREF(result);
  286.                         result=0;
  287.                     }
  288.                 }
  289.             }
  290.  
  291.             FreeArgs(rdargs);
  292.             FreeDosObject( DOS_RDARGS, rdargs );
  293.         }
  294.         else (void)PyErr_NoMemory();
  295.  
  296.         if(free_args) free(args);
  297.         free(argarray);
  298.     }
  299.     else (void)PyErr_NoMemory();
  300.  
  301.     return (PyObject*)result;
  302. }
  303.  
  304.  
  305. static PyObject *
  306. CheckOrWaitSignal(PyObject *self, PyObject *arg, BOOL doWait)
  307. {
  308.     struct {
  309.         PyObject *ob;       // the object, NULL means: only sigmask value
  310.         ULONG sigmask;
  311.     } objs[32];
  312.     int i,listsize = 0;
  313.     PyObject *argo, *result;
  314.     ULONG signal;
  315.  
  316.     if(!PyArg_ParseTuple(arg,"O",&argo)) return NULL;
  317.  
  318.     if(PyInt_Check(argo))
  319.     {
  320.         /* 1 int arg */
  321.         signal=PyInt_AsLong(argo);
  322.         objs[0].ob=NULL;
  323.         objs[0].sigmask=signal;
  324.         listsize++;
  325.     }
  326.     else if(PyList_Check(argo))
  327.     {
  328.         /* 1 list arg */
  329.         int len=PyList_Size(argo);
  330.  
  331.         if(len==0 || len>32)
  332.         {
  333.             PyErr_SetString(PyExc_ValueError,"list size must be 1..32");
  334.             return NULL;
  335.         }
  336.  
  337.         signal = 0;
  338.  
  339.         for(i=0;i<len;i++)
  340.         {
  341.             PyObject *attr;
  342.             PyObject *item = PyList_GetItem(argo,i);
  343.             ULONG s;
  344.  
  345.             if(PyInt_Check(item))
  346.             {
  347.                 s = PyInt_AsLong(item);
  348.                 objs[listsize].ob = NULL;
  349.                 objs[listsize++].sigmask=s;
  350.                 signal |= s;
  351.             }
  352.             else if(attr = PyObject_GetAttrString(item,"signal"))
  353.             {
  354.                 ULONG s = PyInt_AsLong(attr);
  355.  
  356.                 if((s==-1) && PyErr_Occurred())
  357.                 {
  358.                     Py_DECREF(attr);
  359.                     return NULL;
  360.                 }
  361.                 
  362.                 signal |= s;
  363.                 objs[listsize].ob=item;
  364.                 objs[listsize++].sigmask=s;
  365.             }
  366.             else return (PyObject*)PyErr_BadArgument();
  367.         }
  368.     }
  369.     else
  370.     {
  371.         /* other, try signal attribute */
  372.         PyObject *attr;
  373.         if(attr=PyObject_GetAttrString(argo,"signal"))
  374.         {
  375.             /* Found! */
  376.             signal = PyInt_AsLong(attr);
  377.  
  378.             if((signal==-1) && PyErr_Occurred())
  379.             {
  380.                 Py_DECREF(attr);
  381.                 return NULL;
  382.             }
  383.  
  384.             objs[0].ob = attr;
  385.             objs[0].sigmask = signal;
  386.             listsize++;
  387.         }
  388.         else return NULL;
  389.     }
  390.     
  391.     if(doWait)
  392.         signal = Wait(signal);
  393.     else
  394.         signal = CheckSignal(signal);
  395.  
  396.     if(result=PyList_New(0))
  397.     {
  398.         PyObject *tup;
  399.  
  400.         for(i=0;i<listsize;i++)
  401.         {
  402.             if(objs[i].ob && (signal&objs[i].sigmask))
  403.             {
  404.                 if(0!=PyList_Append(result,objs[i].ob))
  405.                 {
  406.                     Py_DECREF(result);
  407.                     return NULL;
  408.                 }
  409.             }
  410.         }
  411.  
  412.         tup=Py_BuildValue("(iO)",signal,result);
  413.         Py_DECREF(result);
  414.         return tup;
  415.     }
  416.     else return NULL;
  417. }
  418.  
  419. static PyObject *
  420. Doslib_WaitSignal(PyObject *self, PyObject *arg)
  421. {
  422.     return CheckOrWaitSignal(self,arg,TRUE);
  423. }
  424.  
  425. static PyObject *
  426. Doslib_CheckSignal(PyObject *self, PyObject *arg)
  427. {
  428.     return CheckOrWaitSignal(self,arg,FALSE);
  429. }
  430.  
  431.  
  432. static PyObject *
  433. Doslib_DateToStr(PyObject *self, PyObject *arg)
  434. {
  435.     // (datestamp[,format=FORMAT_DOS,flags=0]) -> string
  436.  
  437.     struct DateTime dt;
  438.     PyObject *ds_t;
  439.     int flags=0,format=FORMAT_DOS;
  440.     char day[32];
  441.     char date[32];
  442.     char time[32];
  443.  
  444.     if(!PyArg_ParseTuple(arg,"O!|ii",&PyTuple_Type,&ds_t,&format,&flags)) return NULL;
  445.  
  446.     if(!PyArg_ParseTuple(ds_t,"iii;invalid datestamp tuple",
  447.         &dt.dat_Stamp.ds_Days,&dt.dat_Stamp.ds_Minute,&dt.dat_Stamp.ds_Tick)) return NULL;
  448.  
  449.     dt.dat_StrDay=day;
  450.     dt.dat_StrDate=date;
  451.     dt.dat_StrTime=time;
  452.     dt.dat_Flags=flags;
  453.     dt.dat_Format=format;
  454.     DateToStr(&dt);
  455.     return Py_BuildValue("(sss)",dt.dat_StrDay,dt.dat_StrDate,dt.dat_StrTime);  
  456. }
  457.  
  458. static PyObject *
  459. Doslib_StrToDate(PyObject *self, PyObject *arg)
  460. {
  461.     // (datestring[,timestring,format=FORMAT_DOS,flags=0]) -> datestamp
  462.  
  463.     struct DateTime dt;
  464.     
  465.     char *date;
  466.     char *time=NULL;
  467.     int flags=0,format=FORMAT_DOS;
  468.  
  469.     if(!PyArg_ParseTuple(arg,"s|sii",&date,&time,&format,&flags)) return NULL;
  470.  
  471.     memset(&dt,0,sizeof(dt));
  472.     dt.dat_StrDate=date;
  473.     dt.dat_StrTime=time;
  474.     dt.dat_Flags=flags;
  475.     dt.dat_Format=format;
  476.     StrToDate(&dt);
  477.     return Py_BuildValue("(iii)",dt.dat_Stamp.ds_Days,dt.dat_Stamp.ds_Minute,dt.dat_Stamp.ds_Tick);
  478. }
  479.  
  480. static PyObject *
  481. Doslib_CompareDates(PyObject *self, PyObject *arg)      // (ds1, ds2) -> <0,0,>0
  482. {
  483.     PyObject *ds_t1, *ds_t2;
  484.     struct DateStamp ds1,ds2;
  485.  
  486.     if(!PyArg_ParseTuple(arg,"O!O!",
  487.         &PyTuple_Type,&ds_t1,&PyTuple_Type,&ds_t2)) return NULL;
  488.  
  489.     if(!PyArg_ParseTuple(ds_t1,"iii;invalid datestamp tuple",&ds1.ds_Days,&ds1.ds_Minute,&ds1.ds_Tick)) return NULL;
  490.     if(!PyArg_ParseTuple(ds_t2,"iii;invalid datestamp tuple",&ds2.ds_Days,&ds2.ds_Minute,&ds2.ds_Tick)) return NULL;
  491.  
  492.     return PyInt_FromLong(CompareDates(&ds1,&ds2)); 
  493. }
  494.  
  495. static PyObject *
  496. Doslib_DateStamp(PyObject *self, PyObject *arg)     // () -> datestamp
  497. {
  498.     struct DateStamp ds;
  499.     if(!PyArg_NoArgs(arg)) return NULL;
  500.     
  501.     DateStamp(&ds);
  502.     return Py_BuildValue("(iii)",ds.ds_Days,ds.ds_Minute,ds.ds_Tick);
  503. }
  504.  
  505. static PyObject *
  506. Doslib_Info(PyObject *self, PyObject *arg)     // (name) -> infoblock
  507. {
  508.     struct InfoData *_id;
  509.     char *name;
  510.  
  511.     if(!PyArg_ParseTuple(arg,"s",&name)) return NULL;
  512.     if(_id=AllocVec(sizeof(struct InfoData),MEMF_PUBLIC))
  513.     {
  514.         BPTR lock;
  515.         if(lock=Lock(name, SHARED_LOCK))
  516.         {
  517.             if(Info(lock,_id))
  518.             {
  519.                 struct InfoData id;
  520.                 id = *_id;
  521.                 FreeVec(_id);
  522.                 UnLock(lock);
  523.                 return Py_BuildValue("(iiiiiiii)", id.id_NumSoftErrors, id.id_UnitNumber,
  524.                     id.id_DiskState, id.id_NumBlocks, id.id_NumBlocksUsed, id.id_BytesPerBlock,
  525.                     id.id_DiskType, id.id_InUse);
  526.             }
  527.             else
  528.             {
  529.                 (void) check_ok(FALSE);
  530.             }
  531.             FreeVec(_id);
  532.             UnLock(lock);
  533.         }
  534.         else
  535.         {
  536.             (void) check_ok(FALSE);
  537.         }
  538.         return NULL;
  539.     }
  540.     return PyErr_NoMemory();
  541. }
  542.  
  543. static PyObject *
  544. Doslib_Fault(PyObject *self, PyObject *arg)         // (errnum[, header]) -> string
  545. {
  546.     int errnum;
  547.     char *header=NULL;
  548.     char buf[100];
  549.  
  550.     if(!PyArg_ParseTuple(arg,"i|s",&errnum,&header)) return NULL;
  551.     Fault(errnum,header,buf,100);
  552.     return PyString_FromString(buf);
  553. }
  554.  
  555. static PyObject *
  556. Doslib_GetProgramDir(PyObject *self, PyObject *arg) // () -> string
  557. {
  558.     BPTR lock;
  559.     if(!PyArg_NoArgs(arg)) return NULL;
  560.     
  561.     if(lock=GetProgramDir())
  562.     {
  563.         char name[256];
  564.         if(NameFromLock(lock, name, 256))
  565.         {
  566.             return PyString_FromString(name);
  567.         }
  568.         return check_ok(FALSE);
  569.     }
  570.     return PyString_FromString("");
  571. }
  572.  
  573. static PyObject *
  574. Doslib_GetProgramName(PyObject *self, PyObject *arg) // () -> string
  575. {
  576.     char name[256];
  577.     if(!PyArg_NoArgs(arg)) return NULL;
  578.     
  579.     if(GetProgramName(name, 256))
  580.     {
  581.         return PyString_FromString(name);
  582.     }
  583.     return check_ok(FALSE);
  584. }
  585.  
  586. static PyObject *
  587. Doslib_IoErr(PyObject *self, PyObject *arg)         // () -> int
  588. {
  589.     if(!PyArg_NoArgs(arg)) return NULL;
  590.     return PyInt_FromLong(IoErr());
  591. }
  592.  
  593. static PyObject *
  594. Doslib_Inhibit(PyObject *self, PyObject *arg) // (drive [,switch]) -> bool
  595. {
  596.     char *name;
  597.     int swtch=1;
  598.  
  599.     if(!PyArg_ParseTuple(arg,"s|i",&name,&swtch)) return NULL;
  600.  
  601.     return check_ok(Inhibit(name,swtch));
  602. }
  603.  
  604. static PyObject *
  605. Doslib_SetIoErr(PyObject *self, PyObject *arg)      // (int) -> int
  606. {
  607.     int errnum;
  608.  
  609.     if(!PyArg_ParseTuple(arg,"i",&errnum)) return NULL;
  610.     return PyInt_FromLong(SetIoErr(errnum));
  611. }
  612.  
  613. static PyObject *
  614. Doslib_IsFileSystem(PyObject *self, PyObject *arg)      // (string) -> bool
  615. {
  616.     char *name;
  617.  
  618.     if(!PyArg_ParseTuple(arg,"s",&name)) return NULL;
  619.     return PyInt_FromLong(IsFileSystem(name));
  620. }
  621.  
  622. static PyObject *
  623. Doslib_Relabel(PyObject *self, PyObject *arg)   // (oldvolname, newvolname)
  624. {
  625.     char *old, *new;
  626.  
  627.     if(!PyArg_ParseTuple(arg,"ss",&old,&new)) return NULL;
  628.     if(old[strlen(old)-1]!=':')
  629.     {
  630.         PyErr_SetString(PyExc_ValueError,"volume name must end with :");
  631.         return NULL;
  632.     }
  633.     if(new[strlen(new)-1]==':')
  634.     {
  635.         PyErr_SetString(PyExc_ValueError,"new name must not end with :");
  636.         return NULL;
  637.     }
  638.     return check_ok(Relabel(old,new));
  639. }
  640.  
  641. static PyObject *
  642. Doslib_SetProtection(PyObject *self, PyObject *arg) // (file,protbits) -> bool
  643. {
  644.     char *name;
  645.     int pb;
  646.  
  647.     if(!PyArg_ParseTuple(arg,"si",&name,&pb)) return NULL;
  648.  
  649.     return check_ok(SetProtection(name,pb));
  650. }
  651.  
  652. static PyObject *
  653. Doslib_SetFileDate(PyObject *self, PyObject *arg) // (file,datestamp) -> bool
  654. {
  655.     struct DateStamp ds;
  656.     PyObject *ds_t;
  657.     char *name;
  658.  
  659.     if(!PyArg_ParseTuple(arg,"sO!",&name,&PyTuple_Type,&ds_t)) return NULL;
  660.  
  661.     if(!PyArg_ParseTuple(ds_t,"iii;invalid datestamp tuple",
  662.         &ds.ds_Days,&ds.ds_Minute,&ds.ds_Tick)) return NULL;
  663.  
  664.     return check_ok(SetFileDate(name,&ds));
  665. }
  666.  
  667. static PyObject *
  668. Doslib_Examine(PyObject *self, PyObject *arg)       // (filename) -> fib structure
  669. {
  670.     char *name;
  671.     BPTR lock;
  672.     struct FileInfoBlock __aligned fib;
  673.  
  674.     if(!PyArg_ParseTuple(arg,"s",&name)) return NULL;
  675.     if(lock=Lock(name,ACCESS_READ))
  676.     {
  677.         if(Examine(lock,&fib))
  678.         {
  679.             UnLock(lock);
  680.             return Py_BuildValue("(siiiii(iii)sii)",
  681.                 fib.fib_FileName,
  682.                 fib.fib_Size,
  683.                 fib.fib_DirEntryType,
  684.                 fib.fib_Protection,
  685.                 fib.fib_DiskKey,
  686.                 fib.fib_NumBlocks,
  687.                 fib.fib_Date.ds_Days, fib.fib_Date.ds_Minute, fib.fib_Date.ds_Tick,
  688.                 fib.fib_Comment,
  689.                 fib.fib_OwnerUID,
  690.                 fib.fib_OwnerGID);
  691. /******************
  692.             return Py_BuildValue("(iisiiii(iii)sii)",
  693.                 fib.fib_DiskKey,
  694.                 fib.fib_DirEntryType,
  695.                 fib.fib_FileName,
  696.                 fib.fib_Protection,
  697.                 fib.fib_EntryType,
  698.                 fib.fib_Size,
  699.                 fib.fib_NumBlocks,
  700.                 fib.fib_Date.ds_Days, fib.fib_Date.ds_Minute, fib.fib_Date.ds_Tick,
  701.                 fib.fib_Comment,
  702.                 fib.fib_OwnerUID,
  703.                 fib.fib_OwnerGID);
  704. ******************/
  705.         }
  706.         UnLock(lock);
  707.     }
  708.     return check_ok(FALSE);
  709. }
  710.  
  711. static PyObject *
  712. Doslib_SetComment(PyObject *self, PyObject *args)    // (file,comment) -> bool
  713. {
  714.     char *path, *note;
  715.  
  716.     if (!PyArg_ParseTuple(args, "ss", &path,¬e)) return NULL;
  717.     return check_ok(SetComment(path,note));
  718. }
  719.  
  720. static PyObject *
  721. Doslib_SetOwner(PyObject *self, PyObject *args)        // (file, uid, gid) -> bool
  722. {
  723.     char *file;
  724.     int uid, gid;
  725.     LONG guid;
  726.  
  727.     if (!PyArg_ParseTuple(args, "sii", &file,&uid,&gid)) return NULL;
  728.     guid = ((uid&0xFFFF)<<16) | (gid&0xFFFF);
  729.     return check_ok(SetOwner(file,guid));
  730. }
  731.  
  732.  
  733. /* the offset between DateStamp() and time() epoch: */
  734. #define TIME_OFFSET 252457200.0
  735.  
  736. static PyObject *
  737. Doslib_DS2time(PyObject *self, PyObject *args)
  738. {
  739.     struct DateStamp ds;
  740.  
  741.     if(!PyArg_ParseTuple(args,"(iii)",&ds.ds_Days,&ds.ds_Minute,&ds.ds_Tick)) return NULL;
  742.  
  743.     return PyFloat_FromDouble(
  744.         86400.0*ds.ds_Days + 60.0*ds.ds_Minute + ((double)ds.ds_Tick/50.0) + TIME_OFFSET
  745.     );
  746. }
  747.  
  748. static PyObject *
  749. Doslib_time2DS(PyObject *self, PyObject *args)
  750. {
  751.     double t;
  752.     int days,minutes,ticks;
  753.  
  754.     if(!PyArg_ParseTuple(args,"d",&t)) return NULL;
  755.  
  756.     t -= TIME_OFFSET;
  757.     days =  t / 86400.0;
  758.     t -= days*86400.0;
  759.     minutes = t / 60.0;
  760.     t -= minutes*60.0;
  761.     ticks = t*50.0;
  762.  
  763.     return Py_BuildValue("(iii)",days,minutes,ticks);
  764. }
  765.  
  766.  
  767. static PyObject *
  768. Doslib_SetMode( PyObject *self, PyObject *args )
  769. {
  770.         LONG mode;
  771.         BOOL result;
  772.  
  773.         if( !PyArg_ParseTuple( args , "l" , &mode ) ) return NULL;
  774.  
  775.         result = SetMode( Input() , mode );
  776.  
  777.         return Py_BuildValue( "l" , result );
  778. }
  779.  
  780. static PyObject *
  781. Doslib_WaitForChar( PyObject *self, PyObject *args )
  782. {
  783.         LONG timeout;
  784.         BOOL result;
  785.  
  786.         if( !PyArg_ParseTuple( args , "l" , &timeout ) ) return NULL;
  787.  
  788.         result = WaitForChar( Input() , timeout );
  789.  
  790.         if( result == -1 )      /* Just to be safe, as I don't know if Python           */
  791.         {                       /* considers -1 as true (like AmigaOS does apparently). */
  792.                 result = 1;
  793.         }
  794.  
  795.         return Py_BuildValue( "l" , result );
  796. }
  797.  
  798. static PyObject *
  799. Doslib_GetChar( PyObject *self, PyObject *args )
  800. {
  801.         char buffer;
  802.         LONG result;
  803.  
  804.         if( !PyArg_ParseTuple( args , "" ) ) return NULL;
  805.  
  806.         result = Read( Input() , &buffer , 1L );
  807.  
  808.         if( result == 0 )                       /* Did we get an EOF?      */
  809.         {
  810.             return Py_BuildValue( "s" , "" );
  811.         }
  812.         else if( result == -1 )                 /* Or maybe even an error? */
  813.         {
  814.             return NULL;
  815.         }
  816.         else
  817.         {
  818.             return Py_BuildValue( "c" , buffer );
  819.         }
  820. }
  821.  
  822.  
  823. static PyObject *
  824. Doslib_PutChar( PyObject *self, PyObject *args )
  825. {
  826.     char buffer;
  827.  
  828.     if( !PyArg_ParseTuple( args , "c" , &buffer ) ) return NULL;
  829.  
  830.     if( Write( Output() , &buffer , 1L ) == 1 )
  831.     {
  832.         return Py_BuildValue( "i" , 1 );
  833.     }
  834.     else                                        /* An error occurred. */
  835.     {
  836.         return NULL;
  837.     }
  838. }
  839.  
  840. static PyObject *
  841. Doslib_PutString( PyObject *self, PyObject *args )
  842. {
  843.     char *buffer;
  844.     LONG bufferlen;
  845.  
  846.     if( !PyArg_ParseTuple( args , "s" , &buffer ) ) return NULL;
  847.  
  848.     bufferlen = strlen( buffer );
  849.  
  850.  
  851.     if( Write( Output() , buffer , bufferlen ) == bufferlen )
  852.     {
  853.         return Py_BuildValue( "i" , 1 );
  854.     }
  855.     else                                        /* An error occurred. */
  856.     {
  857.         return NULL;
  858.     }
  859. }
  860.  
  861.  
  862. /*** FUNCTIONS FROM THE MODULE ***/
  863.  
  864. static struct PyMethodDef Doslib_global_methods[] = {
  865.     {"ReadArgs", Doslib_ReadArgs, 1},
  866.     {"WaitSignal", Doslib_WaitSignal, 1},
  867.     {"CheckSignal", Doslib_CheckSignal, 1},
  868.     {"CompareDates", Doslib_CompareDates, 1},
  869.     {"DateStamp", Doslib_DateStamp, 0},
  870.     {"DateToStr", Doslib_DateToStr, 1},
  871.     {"StrToDate", Doslib_StrToDate, 1},
  872.     {"Fault", Doslib_Fault, 1},
  873.     {"GetProgramDir", Doslib_GetProgramDir, 0},
  874.     {"GetProgramName", Doslib_GetProgramName, 0},
  875.     {"Inhibit", Doslib_Inhibit, 1},
  876.     {"Info", Doslib_Info, 1},
  877.     {"IoErr", Doslib_IoErr, 0},
  878.     {"SetIoErr", Doslib_SetIoErr, 1},
  879.     {"IsFileSystem", Doslib_IsFileSystem, 1},
  880.     {"Relabel", Doslib_Relabel, 1},
  881.     {"SetProtection", Doslib_SetProtection, 1},
  882.     {"SetComment", Doslib_SetComment, 1},
  883.     {"SetFileDate", Doslib_SetFileDate, 1},
  884.     {"SetOwner", Doslib_SetOwner, 1},
  885.     {"Examine", Doslib_Examine, 1},
  886.     {"DS2time", Doslib_DS2time, 1},
  887.     {"time2DS", Doslib_time2DS, 1},
  888.     {"SetMode", Doslib_SetMode, 1},
  889.     {"WaitForChar", Doslib_WaitForChar, 1},
  890.     {"GetChar", Doslib_GetChar, 1},
  891.     {"PutChar", Doslib_PutChar, 1},
  892.     {"PutString", Doslib_PutString, 1},
  893.     {NULL,      NULL}       /* sentinel */
  894. };
  895.  
  896. void
  897. initDoslib Py_PROTO((void))
  898. {
  899.     PyObject *m, *d;
  900.  
  901.     m = Py_InitModule("Doslib", Doslib_global_methods);
  902.     d = PyModule_GetDict(m);
  903.  
  904.     /* Initialize error exception */
  905.     error = PyErr_NewException("Doslib.error", NULL, NULL);
  906.     if (error != NULL)
  907.         PyDict_SetItemString(d, "error", error);
  908. }
  909.