G:/ScriptBasic/source/commands/file.c

Go to the documentation of this file.
00001 /*file.c
00002 
00003 --GNU LGPL
00004 This library is free software; you can redistribute it and/or
00005 modify it under the terms of the GNU Lesser General Public
00006 License as published by the Free Software Foundation; either
00007 version 2.1 of the License, or (at your option) any later version.
00008 
00009 This library is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 Lesser General Public License for more details.
00013 
00014 You should have received a copy of the GNU Lesser General Public
00015 License along with this library; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 */
00019 
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <string.h>
00023 #if (!defined(_WIN32) && !defined(__MACOS__))
00024 #include <sys/file.h>
00025 #endif
00026 
00027 #include "../command.h"
00028 #include "../filesys.h"
00029 #include "../match.h"
00030 #include "../matchc.h"
00031 
00032 #define THISFILEP  pFCO->Descriptor[FileNumber].fp
00033 #define THISSOCKET pFCO->Descriptor[FileNumber].sp
00034 /*
00035 File functions and commands
00036 
00037 This file contains the code for the commands and functions that deal with files.
00038 */
00039 #if (!defined(_WIN32) && !defined(__MACOS__))
00040 int stricmp(char *,char*);
00041 #endif
00042 
00043 #define MAXFILES 512
00044 typedef struct _FileCommandObject {
00045   union {
00046     FILE *fp;  /* the file pointer to the opened file */
00047     SOCKET sp;
00048     }Descriptor[MAXFILES];
00049   long RecordSize[MAXFILES]; /* the length of a record */
00050   char mode[MAXFILES]; /* the mode the file was opened 'i', 'o', 'a', 'r' or 'b' */
00051                        /* 's' for client sockets */
00052                        /* '\0' for not opened file or socket */
00053   int SocketState[MAXFILES]; /*0 normal, -1 kind of EOF */
00054   } FileCommandObject, *pFileCommandObject;
00055 
00056 static void close_all_files(pExecuteObject pEo){
00057   pFileCommandObject pFCO;
00058   long FileNumber;
00059 
00060   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00061   for( FileNumber = 0 ; FileNumber < MAXFILES ; FileNumber++ ){
00062     if( pFCO->mode[FileNumber] ){
00063       if( pFCO->mode[FileNumber] == 's' )
00064         HOOK_TCPCLOSE(THISSOCKET);
00065       else
00066         HOOK_FCLOSE(THISFILEP);
00067       }
00068     THISFILEP = NULL;
00069     }
00070   }
00071 
00072 static int init(pExecuteObject pEo){
00073 #define INITIALIZE init(pEo)
00074   pFileCommandObject pFCO;
00075   int i;
00076 
00077   /* initialize only once */
00078   if( PARAMPTR(CMD_OPEN) )return 0;
00079   PARAMPTR(CMD_OPEN) = ALLOC(sizeof(FileCommandObject));
00080   if( PARAMPTR(CMD_OPEN) == NULL )return COMMAND_ERROR_MEMORY_LOW;
00081 
00082   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00083   for( i=0 ; i < MAXFILES ; i++ )
00084     pFCO->mode[i] = (char)0;
00085   FINALPTR(CMD_OPEN) = close_all_files;
00086   return 0;
00087   }
00088 
00089 /* Create the directory for a file in case it does not exists. */
00090 static void prepare_directory(pExecuteObject pEo,char *pszFileName){
00091   int i;
00092   char *s;
00093 
00094   s = pszFileName + (i=strlen(pszFileName)) -1;
00095   while( i ){
00096 #ifdef __MACOS__
00097     if( *s == ':' ){
00098 #else
00099     if( *s == '/' || *s == '\\' ){
00100 #endif
00101       i = *s;
00102       *s = (char)0;
00103       HOOK_MAKEDIRECTORY(pszFileName);
00104       *s = (char)i;
00105       return;
00106       }
00107     i--;
00108     s--;
00109     }
00110   }
00111 
00112 /* check that a file name is secure */
00113 static int FileIsSecure(pExecuteObject pEo,VARIABLE vFileName){
00114   unsigned long i;
00115 
00116   for( i=0 ; i < STRLEN(vFileName) ; i++ ){
00117     if( STRINGVALUE(vFileName)[i] == 0 )return 0;
00118     }
00119   return 1;
00120   }
00121 
00122 #define SECUREFILE(x) if( ! FileIsSecure(pEo,x) )ERROR(COMMAND_ERROR_FILE_CANNOT_BE_OPENED);
00123 
00157 COMMAND(OPEN)
00158 #if NOTIMP_OPEN
00159 NOTIMPLEMENTED;
00160 #else
00161 
00162 
00163   long FileNumber,RecLen;
00164   char *FileName;
00165   char *ModeString;
00166   pFileCommandObject pFCO;
00167   VARIABLE Op1,FN,vLEN;
00168 
00169   INITIALIZE;
00170   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00171 
00172   Op1 = CONVERT2STRING(_EVALUATEEXPRESSION(PARAMETERNODE));
00173   ASSERTOKE;
00174   NEXTPARAMETER;
00175   ModeString = pEo->StringTable+pEo->CommandArray[_ActualNode-1].Parameter.CommandArgument.Argument.szStringValue;
00176   NEXTPARAMETER;
00177   FN = _EVALUATEEXPRESSION(PARAMETERNODE);
00178   ASSERTOKE;
00179   NEXTPARAMETER;
00180   vLEN = CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE));
00181   ASSERTOKE;
00182 
00183   if( memory_IsUndef(vLEN) )ERROR(COMMAND_ERROR_BAD_RECORD_LENGTH);
00184   RecLen = LONGVALUE(vLEN); /* the default record length is 1 */
00185   if( RecLen < 1 )ERROR(COMMAND_ERROR_BAD_RECORD_LENGTH);
00186 
00187   if( memory_IsUndef(FN) )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
00188   if( TYPE(FN) == VTYPE_LONG && LONGVALUE(FN) == 0 ){/* we have to automatically allocate the file number */
00189 
00190     for( FileNumber = 1 ; FileNumber < MAXFILES ; FileNumber++ )
00191       if( ! pFCO->mode[FileNumber] )break;
00192     if( FileNumber >= MAXFILES )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
00193     LONGVALUE(FN) = FileNumber;
00194     }
00195   FileNumber = LONGVALUE(CONVERT2LONG(FN));
00196 
00197   if( FileNumber < 1 || FileNumber > MAXFILES )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
00198   FileNumber --;
00199   if( pFCO->mode[FileNumber] )ERROR(COMMAND_ERROR_FILE_NUMBER_IS_USED);
00200 
00201   FileName = ALLOC(STRLEN(Op1)+1);
00202   if( FileName == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
00203   memcpy(FileName,STRINGVALUE(Op1),STRLEN(Op1));
00204   FileName[STRLEN(Op1)] = (char)0;
00205 
00206   if( !stricmp(ModeString,"socket") || !stricmp(ModeString,"socket_binary")){
00207     if( HOOK_TCPCONNECT(&(THISSOCKET),FileName) ){
00208       FREE(FileName);
00209       pFCO->mode[FileNumber] = (char)0;
00210       ERROR(COMMAND_ERROR_FILE_CANNOT_BE_OPENED);
00211       }
00212     pFCO->mode[FileNumber] = 's';
00213     FREE(FileName);
00214     pFCO->RecordSize[FileNumber] = RecLen;
00215     pFCO->SocketState[FileNumber] = 0;
00216     RETURN;
00217     }else
00218   if( !stricmp(ModeString,"input") ){
00219     pFCO->mode[FileNumber] = 'i';
00220     if( HOOK_ISDIR(FileName) )
00221       THISFILEP = NULL;
00222     else
00223       THISFILEP = HOOK_FOPEN(FileName,"r");
00224     }else
00225   if( !stricmp(ModeString,"input_binary") ){
00226     pFCO->mode[FileNumber] = 'i';
00227     if( HOOK_ISDIR(FileName) )
00228       THISFILEP = NULL;
00229     else
00230       THISFILEP = HOOK_FOPEN(FileName,"rb");
00231     }else
00232   if( !stricmp(ModeString,"output") ){
00233     pFCO->mode[FileNumber] = 'o';
00234     if( HOOK_ISDIR(FileName) )
00235       THISFILEP = NULL;
00236     else{
00237       prepare_directory(pEo,FileName);
00238       THISFILEP = HOOK_FOPEN(FileName,"w");
00239       }
00240     }else
00241   if( !stricmp(ModeString,"output_binary") ){
00242     pFCO->mode[FileNumber] = 'o';
00243     if( HOOK_ISDIR(FileName) )
00244       THISFILEP = NULL;
00245     else{
00246       prepare_directory(pEo,FileName);
00247       THISFILEP = HOOK_FOPEN(FileName,"wb");
00248       }
00249     }else
00250   if( !stricmp(ModeString,"append") ){
00251     pFCO->mode[FileNumber] = 'a';
00252     if( HOOK_ISDIR(FileName) )
00253       THISFILEP = NULL;
00254     else{
00255       prepare_directory(pEo,FileName);
00256       THISFILEP = HOOK_FOPEN(FileName,"a");
00257       }
00258     }else
00259   if( !stricmp(ModeString,"append_binary") ){
00260     pFCO->mode[FileNumber] = 'a';
00261     if( HOOK_ISDIR(FileName) )
00262       THISFILEP = NULL;
00263     else{
00264       prepare_directory(pEo,FileName);
00265       THISFILEP = HOOK_FOPEN(FileName,"ab");
00266       }
00267     }else
00268   if( !stricmp(ModeString,"random") ){
00269     pFCO->mode[FileNumber] = 'r';
00270     if( HOOK_ISDIR(FileName) )
00271       THISFILEP = NULL;
00272     else{
00273       prepare_directory(pEo,FileName);
00274       THISFILEP = HOOK_FOPEN(FileName,"r+");
00275       if( THISFILEP == NULL )
00276         THISFILEP = HOOK_FOPEN(FileName,"w+");
00277       }
00278     }else
00279   if( !stricmp(ModeString,"binary") || !stricmp(ModeString,"random_binary") ){
00280     pFCO->mode[FileNumber] = 'b';
00281     if( HOOK_ISDIR(FileName) )
00282       THISFILEP = NULL;
00283     else{
00284       prepare_directory(pEo,FileName);
00285       THISFILEP = HOOK_FOPEN(FileName,"rb+");
00286       if( THISFILEP == NULL )
00287         THISFILEP = HOOK_FOPEN(FileName,"wb+");
00288       }
00289     }
00290   FREE(FileName);
00291   if( THISFILEP == NULL ){
00292     pFCO->mode[FileNumber] = (char)0;
00293     ERROR(COMMAND_ERROR_FILE_CANNOT_BE_OPENED);
00294     }
00295   pFCO->RecordSize[FileNumber] = RecLen;
00296 #endif
00297 END
00298 
00299 static char *ReadFileLine(pExecuteObject pEo,
00300                           FILE *fp,
00301                           unsigned long *plCharactersRead,
00302                           int (*pfExtIn)(void *)){
00303   char *s,*r;
00304   unsigned long lBufferSize;
00305   int ch;
00306 #define BUFFER_INCREASE 256
00307 
00308   s = ALLOC(BUFFER_INCREASE);
00309   if( s == NULL )return NULL;
00310   lBufferSize = BUFFER_INCREASE;
00311   *plCharactersRead = 0L;
00312   while( 1 ){
00313     if( (ch= (pfExtIn == NULL ? HOOK_FGETC(fp) : pfExtIn(pEo->pEmbedder) )) == EOF )break;
00314     if( lBufferSize <= *plCharactersRead ){
00315       r = ALLOC(lBufferSize+BUFFER_INCREASE);
00316       if( r == NULL ){
00317         FREE(s);
00318         return NULL;
00319         }
00320       memcpy(r,s,lBufferSize);
00321       lBufferSize += BUFFER_INCREASE;
00322       FREE(s);
00323       s = r;
00324       }
00325     s[(*plCharactersRead)++] = ch;
00326     if( ch == '\n' )break;
00327     }
00328   return s;
00329   }
00330 
00331 static char *ReadSocketLine(pExecuteObject pEo,
00332                             SOCKET sp,
00333                             unsigned long *plCharactersRead){
00334   char *s,*r;
00335   unsigned long lBufferSize;
00336   char ch;
00337 #define BUFFER_INCREASE 256
00338 
00339   s = ALLOC(BUFFER_INCREASE);
00340   if( s == NULL )return NULL;
00341   lBufferSize = BUFFER_INCREASE;
00342   *plCharactersRead = 0L;
00343   while( 1 ){
00344     if( HOOK_TCPRECV(sp,&ch,1,0) == 0 ){
00345       break;
00346       }
00347     if( lBufferSize <= *plCharactersRead ){
00348       r = ALLOC(lBufferSize+BUFFER_INCREASE);
00349       if( r == NULL ){
00350         FREE(s);
00351         return NULL;
00352         }
00353       memcpy(r,s,lBufferSize);
00354       lBufferSize += BUFFER_INCREASE;
00355       FREE(s);
00356       s = r;
00357       }
00358     s[(*plCharactersRead)++] = ch;
00359     if( ch == '\n' )break;
00360     }
00361   return s;
00362   }
00363 
00364 
00365 
00388 COMMAND(LINPUTF)
00389 #if NOTIMP_LINPUTF
00390 NOTIMPLEMENTED;
00391 #else
00392 
00393   long FileNumber;
00394   pFileCommandObject pFCO;
00395   VARIABLE Result;
00396   LEFTVALUE LetThisVariable;
00397   unsigned long lCharactersRead;
00398   char *s;
00399   long refcount;
00400 
00401   INITIALIZE;
00402   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00403 
00404   FileNumber = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
00405   ASSERTOKE;
00406   NEXTPARAMETER;
00407   /* we get the pointer to the variable that points to the value */
00408   LetThisVariable = EVALUATELEFTVALUE(PARAMETERNODE);
00409   ASSERTOKE;
00410   DEREFERENCE(LetThisVariable)
00411 
00412   if( FileNumber < 1 || FileNumber > MAXFILES )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
00413   FileNumber --;
00414   if( ! pFCO->mode[FileNumber] )ERROR(COMMAND_ERROR_FILE_IS_NOT_OPENED);
00415 
00416   if( pFCO->mode[FileNumber] == 's' ){
00417     s = ReadSocketLine(pEo,THISSOCKET,&lCharactersRead);
00418     if( lCharactersRead == 0 )pFCO->SocketState[FileNumber] = -1;
00419     }
00420   else
00421     s = ReadFileLine(pEo,THISFILEP,&lCharactersRead,NULL);
00422   if( s == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
00423   Result = NEWSTRING(lCharactersRead);
00424   memcpy(STRINGVALUE(Result),s,lCharactersRead);
00425   FREE(s);
00426 
00427   /* if this variable had value assigned to it then release that value */
00428   if( *LetThisVariable )memory_ReleaseVariable(pEo->pMo,*LetThisVariable);
00429 
00430   /* and finally assign the code to the variable */
00431   *LetThisVariable = Result;
00432 
00433 #endif
00434 END
00435 
00436 COMMAND(LINPUT)
00437 #if NOTIMP_LINPUT
00438 NOTIMPLEMENTED;
00439 #else
00440 
00441   VARIABLE Result;
00442   LEFTVALUE LetThisVariable;
00443   unsigned long lCharactersRead;
00444   char *s;
00445   long refcount;
00446 
00447   INITIALIZE;
00448 
00449   /* we get the pointer to the variable that points to the value */
00450   LetThisVariable = EVALUATELEFTVALUE(PARAMETERNODE);
00451   ASSERTOKE;
00452   DEREFERENCE(LetThisVariable)
00453 
00454 
00455   s = ReadFileLine(pEo,stdin,&lCharactersRead,(int (*)(void *))pEo->fpStdinFunction);
00456   if( s == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
00457   Result = NEWSTRING(lCharactersRead);
00458   memcpy(STRINGVALUE(Result),s,lCharactersRead);
00459   FREE(s);
00460 
00461   /* if this variable had value assigned to it then release that value */
00462   if( *LetThisVariable )memory_ReleaseVariable(pEo->pMo,*LetThisVariable);
00463 
00464   /* and finally assign the code to the variable */
00465   *LetThisVariable = Result;
00466 #endif
00467 END
00468 
00475 COMMAND(EOFFUN)
00476 #if NOTIMP_EOFFUN
00477 NOTIMPLEMENTED;
00478 #else
00479 
00480   long FileNumber;
00481   pFileCommandObject pFCO;
00482   NODE nItem;
00483 
00484   INITIALIZE;
00485   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00486 
00487   USE_CALLER_MORTALS;
00488 
00489   nItem = PARAMETERLIST;
00490   FileNumber = LONGVALUE(CONVERT2LONG(_EVALUATEEXPRESSION(CAR(nItem))));
00491   ASSERTOKE;
00492 
00493   if( FileNumber < 1 || FileNumber > MAXFILES )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
00494   FileNumber --;
00495   if( ! pFCO->mode[FileNumber] )ERROR(COMMAND_ERROR_FILE_IS_NOT_OPENED);
00496 
00497   if( pFCO->mode[FileNumber] == 's' ){
00498     RESULT = NEWMORTALLONG;
00499     ASSERTNULL(RESULT)
00500     LONGVALUE(RESULT) = (long)pFCO->SocketState[FileNumber];
00501     }else{
00502     RESULT = NEWMORTALLONG;
00503     ASSERTNULL(RESULT)
00504     if( HOOK_FEOF(THISFILEP) )
00505       LONGVALUE(RESULT) = -1L;
00506     else
00507       LONGVALUE(RESULT) =  0L;
00508     }
00509 #endif
00510 END
00511 
00536 COMMAND(INPUTFUN)
00537 #if NOTIMP_INPUTFUN
00538 NOTIMPLEMENTED;
00539 #else
00540 
00541 
00542   long FileNumber,BytesToRead,CharsRead;
00543   pFileCommandObject pFCO;
00544   NODE nItem;
00545   FILE *fp;
00546   VARIABLE fpN,vBTR;
00547   char *s;
00548   int ch;
00549   int (*pfExtIn)(void *); /* function to return a single character from the embedder standard input*/
00550 
00551   INITIALIZE;
00552   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00553 
00554   USE_CALLER_MORTALS;
00555 
00556   nItem = PARAMETERLIST;
00557   vBTR = EVALUATEEXPRESSION(CAR(nItem));
00558   ASSERTOKE;
00559   if( memory_IsUndef(vBTR) ){
00560     /* we won't read anything because the number of characters is undefined, and therefore the
00561        result is undef, but we still evaluate the second argument if any */
00562     nItem = CDR(nItem);
00563     if( nItem ){
00564       _EVALUATEEXPRESSION(CAR(nItem));
00565       ASSERTOKE;
00566 
00567       }
00568     RESULT = NULL;
00569     RETURN;
00570     }
00571   BytesToRead = GETLONGVALUE(vBTR);
00572   nItem = CDR(nItem);
00573   if( nItem ){
00574     fpN = _EVALUATEEXPRESSION(CAR(nItem));
00575     ASSERTOKE;
00576 
00577     if( ! memory_IsUndef(fpN) ){
00578       FileNumber = GETLONGVALUE(fpN);
00579 
00580       if( FileNumber < 1 || FileNumber > MAXFILES )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
00581       FileNumber --;
00582       if( ! pFCO->mode[FileNumber] )ERROR(COMMAND_ERROR_FILE_IS_NOT_OPENED);
00583       BytesToRead *= pFCO->RecordSize[FileNumber];
00584       fp = THISFILEP;
00585       }else fp = stdin;
00586 
00587     }else{
00588     if( pEo->fpStdinFunction != NULL ){
00589       pfExtIn = pEo->fpStdinFunction;
00590       RESULT = NEWMORTALSTRING(BytesToRead);
00591       ASSERTNULL(RESULT)
00592       s = STRINGVALUE(RESULT);
00593       CharsRead = 0;
00594       while( BytesToRead && ( ch = pfExtIn(pEo->pEmbedder) ) != EOF ){
00595         *s++ = ch;
00596         BytesToRead --;
00597         CharsRead ++;
00598         }
00599       STRLEN(RESULT) = CharsRead;
00600       RETURN;
00601       }
00602     fp = stdin;
00603     }
00604   RESULT = NEWMORTALSTRING(BytesToRead);
00605   ASSERTNULL(RESULT)
00606   if( pFCO->mode[FileNumber] == 's' ){
00607     STRLEN(RESULT) = HOOK_TCPRECV(THISSOCKET,STRINGVALUE(RESULT),BytesToRead,0);
00608     if( STRLEN(RESULT) == 0 )
00609       pFCO->SocketState[FileNumber] = -1;
00610     }else{
00611       s = STRINGVALUE(RESULT);
00612       CharsRead = 0;
00613       while( BytesToRead && ( ch = HOOK_FGETC(fp) ) != EOF ){
00614         *s++ = ch;
00615         BytesToRead --;
00616         CharsRead ++;
00617         }
00618       STRLEN(RESULT) = CharsRead;
00619     }
00620 
00621 #endif
00622 END
00623 
00631 COMMAND(CLOSE)
00632 #if NOTIMP_CLOSE
00633 NOTIMPLEMENTED;
00634 #else
00635 
00636   long FileNumber;
00637   pFileCommandObject pFCO;
00638 
00639   INITIALIZE;
00640   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00641   FileNumber = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
00642   ASSERTOKE;
00643 
00644   if( FileNumber < 1 || FileNumber > MAXFILES )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
00645   FileNumber --;
00646   if( ! pFCO->mode[FileNumber] )ERROR(COMMAND_ERROR_FILE_IS_NOT_OPENED);
00647   if( pFCO->mode[FileNumber] == 's' )
00648     HOOK_TCPCLOSE(THISSOCKET);
00649   else
00650     HOOK_FCLOSE(THISFILEP);
00651   pFCO->mode[FileNumber] = (char)0;
00652   THISFILEP = NULL;
00653 #endif
00654 END
00655 
00662 COMMAND(RESET)
00663 #if NOTIMP_RESET
00664 NOTIMPLEMENTED;
00665 #else
00666 
00667   long FileNumber;
00668   pFileCommandObject pFCO;
00669 
00670   INITIALIZE;
00671   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00672   for( FileNumber = 0 ; FileNumber < MAXFILES ; FileNumber++ ){
00673     if( pFCO->mode[FileNumber] )
00674       if( pFCO->mode[FileNumber] == 's' )
00675         HOOK_TCPCLOSE(THISSOCKET);
00676       else
00677         HOOK_FCLOSE(THISFILEP);
00678     pFCO->mode[FileNumber] = (char)0;
00679     THISFILEP = NULL;
00680     }
00681 #endif
00682 END
00683 
00706 COMMAND(SEEK)
00707 #if NOTIMP_SEEK
00708 NOTIMPLEMENTED;
00709 #else
00710 
00711 
00712   long FileNumber,Position;
00713   pFileCommandObject pFCO;
00714 
00715   INITIALIZE;
00716   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00717   FileNumber = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
00718   ASSERTOKE;
00719   if( FileNumber < 1 || FileNumber > MAXFILES )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
00720   FileNumber --;
00721   if( ! pFCO->mode[FileNumber] )ERROR(COMMAND_ERROR_FILE_IS_NOT_OPENED);
00722   if( pFCO->mode[FileNumber] == 's' )ERROR(COMMAND_ERROR_SOCKET_FILE);
00723   NEXTPARAMETER;
00724   Position = pFCO->RecordSize[FileNumber] * LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
00725   ASSERTOKE;
00726 
00727   fflush(THISFILEP);
00728   fseek(THISFILEP,Position,SEEK_SET);
00729 
00730 #endif
00731 END
00732 
00749 COMMAND(TRUNCATEF)
00750 #if NOTIMP_TRUNCATEF
00751 NOTIMPLEMENTED;
00752 #else
00753 
00754 
00755   long FileNumber,Position;
00756   pFileCommandObject pFCO;
00757 
00758   INITIALIZE;
00759   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00760   FileNumber = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
00761   ASSERTOKE;
00762   if( FileNumber < 1 || FileNumber > MAXFILES )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
00763   FileNumber --;
00764   if( ! pFCO->mode[FileNumber] )ERROR(COMMAND_ERROR_FILE_IS_NOT_OPENED);
00765   if( pFCO->mode[FileNumber] == 's' )ERROR(COMMAND_ERROR_SOCKET_FILE);
00766   NEXTPARAMETER;
00767   Position = pFCO->RecordSize[FileNumber] * LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
00768   ASSERTOKE;
00769 
00770   fflush(THISFILEP);
00771   HOOK_TRUNCATE(THISFILEP,Position);
00772 
00773 #endif
00774 END
00783 COMMAND(REWIND)
00784 #if NOTIMP_REWIND
00785 NOTIMPLEMENTED;
00786 #else
00787 
00788 
00789   long FileNumber;
00790   pFileCommandObject pFCO;
00791 
00792   INITIALIZE;
00793   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00794   FileNumber = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
00795   ASSERTOKE;
00796   if( FileNumber < 1 || FileNumber > MAXFILES )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
00797   FileNumber --;
00798   if( ! pFCO->mode[FileNumber] )ERROR(COMMAND_ERROR_FILE_IS_NOT_OPENED);
00799   if( pFCO->mode[FileNumber] == 's' )ERROR(COMMAND_ERROR_SOCKET_FILE);
00800 
00801   fflush(THISFILEP);
00802   fseek(THISFILEP,0L,SEEK_SET);
00803 
00804 #endif
00805 END
00806 
00828 COMMAND(LOC)
00829 #if NOTIMP_LOC
00830 NOTIMPLEMENTED;
00831 #else
00832 
00833 
00834   VARIABLE Op1;
00835   long FileNumber;
00836   pFileCommandObject pFCO;
00837 
00838   INITIALIZE;
00839   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00840 
00841   /* this is an operator and not a command, therefore we do not have our own mortal list */
00842   USE_CALLER_MORTALS;
00843 
00844   /* evaluate the parameter */
00845   Op1 = EVALUATEEXPRESSION(CAR(PARAMETERLIST));
00846   ASSERTOKE;
00847 
00848   if( memory_IsUndef(Op1) ){
00849     RESULT = NULL;
00850     RETURN;
00851     }
00852 
00853   FileNumber = LONGVALUE(CONVERT2LONG(Op1));
00854   RESULT = NULL;
00855   if( FileNumber < 1 || FileNumber > MAXFILES )RETURN;
00856   FileNumber --;
00857   if( ! pFCO->mode[FileNumber] )RETURN;
00858   if( pFCO->mode[FileNumber] == 's' )RESULT;
00859 
00860   RESULT = NEWMORTALLONG;
00861   ASSERTNULL(RESULT)
00862   LONGVALUE(RESULT) = (long)(ftell(THISFILEP) / pFCO->RecordSize[FileNumber]);
00863 
00864 #endif
00865 END
00866 
00877 COMMAND(LOF)
00878 #if NOTIMP_LOF
00879 NOTIMPLEMENTED;
00880 #else
00881 
00882 
00883   VARIABLE Op1;
00884   long FileNumber,SavePosition;
00885   pFileCommandObject pFCO;
00886 
00887   INITIALIZE;
00888   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00889 
00890   /* this is an operator and not a command, therefore we do not have our own mortal list */
00891   USE_CALLER_MORTALS;
00892 
00893   /* evaluate the parameter */
00894   Op1 = EVALUATEEXPRESSION(CAR(PARAMETERLIST));
00895   ASSERTOKE;
00896 
00897   if( memory_IsUndef(Op1) ){
00898     RESULT = NULL;
00899     RETURN;
00900     }
00901 
00902   FileNumber = LONGVALUE(CONVERT2LONG(Op1));
00903   RESULT = NULL;
00904   if( FileNumber < 1 || FileNumber > MAXFILES )RETURN;
00905   FileNumber --;
00906   if( ! pFCO->mode[FileNumber] )RETURN;
00907   if( pFCO->mode[FileNumber] == 's' )RETURN;
00908 
00909   RESULT = NEWMORTALLONG;
00910   ASSERTNULL(RESULT)
00911   SavePosition = ftell(THISFILEP);
00912   fseek(THISFILEP,0,SEEK_END);
00913   LONGVALUE(RESULT) = (long)(ftell(THISFILEP) / pFCO->RecordSize[FileNumber]);
00914   fseek(THISFILEP,SavePosition,SEEK_SET);
00915 
00916 #endif
00917 END
00918 
00926 COMMAND(FREEFILE)
00927 #if NOTIMP_FREEFILE
00928 NOTIMPLEMENTED;
00929 #else
00930 
00931 
00932   VARIABLE Op1;
00933   long FileNumber,Range;
00934   pFileCommandObject pFCO;
00935   NODE nItem;
00936 
00937   INITIALIZE;
00938   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
00939 
00940   /* this is an operator and not a command, therefore we do not have our own mortal list */
00941   USE_CALLER_MORTALS;
00942 
00943   /* evaluate the parameter */
00944   if( nItem = PARAMETERLIST ){
00945     Op1 = EVALUATEEXPRESSION(CAR(PARAMETERLIST));
00946     ASSERTOKE;
00947     if( memory_IsUndef(Op1) )
00948       Range = -1;
00949     else
00950       Range = LONGVALUE(CONVERT2LONG(Op1));
00951     }else Range = -1;
00952 
00953   if( Range == -1 ){
00954     for( FileNumber = 1 ; FileNumber < MAXFILES ; FileNumber++ )
00955       if( ! pFCO->mode[FileNumber] ){
00956         Range = -2;
00957         break;
00958         }
00959     }else
00960   if( Range == 0 ){
00961     for( FileNumber = 1 ; FileNumber < 255 ; FileNumber++ )
00962       if( ! pFCO->mode[FileNumber]  ){
00963         Range = -2;
00964         break;
00965         }
00966     }else{
00967 
00968     for( FileNumber = 255 ; FileNumber < MAXFILES ; FileNumber++ )
00969       if( ! pFCO->mode[FileNumber]  ){
00970         Range = -2;
00971         break;
00972         }
00973     }
00974   if( Range != -2 ){
00975     RESULT = NULL;
00976     RETURN;
00977     }
00978 
00979   RESULT = NEWMORTALLONG;
00980   ASSERTNULL(RESULT)
00981   LONGVALUE(RESULT) = FileNumber+1;
00982 
00983 #endif
00984 END
00985 
00998 COMMAND(FPRINT)
00999 #if NOTIMP_FPRINT
01000 NOTIMPLEMENTED;
01001 #else
01002 
01003   char buffer[80]; /* should be enough to print a long or a double */
01004   NODE nItem;
01005   VARIABLE ItemResult;
01006 
01007   long FileNumber;
01008   pFileCommandObject pFCO;
01009   char *s;
01010   unsigned long slen;
01011 
01012   INITIALIZE;
01013   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
01014 
01015   nItem = PARAMETERNODE;
01016   FileNumber = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(nItem)));
01017   ASSERTOKE;
01018   if( FileNumber < 1 || FileNumber > MAXFILES )RETURN;
01019   FileNumber --;
01020   if( ! pFCO->mode[FileNumber] )RETURN;
01021 
01022 
01023   NEXTPARAMETER;
01024   nItem = PARAMETERNODE;
01025 
01026   while( nItem ){
01027     ItemResult = EVALUATEEXPRESSION(CAR(nItem));
01028     ASSERTOKE;
01029 
01030 
01031     if( memory_IsUndef(ItemResult) ){
01032       s = "undef";
01033       slen = 5;
01034       }
01035     else
01036     switch( TYPE(ItemResult) ){
01037       case VTYPE_LONG:
01038         sprintf(buffer,"%ld",LONGVALUE(ItemResult));
01039         s = buffer;
01040         slen = strlen(buffer);
01041         break;
01042       case VTYPE_DOUBLE:
01043         sprintf(buffer,"%lf",DOUBLEVALUE(ItemResult));
01044         s = buffer;
01045         slen = strlen(buffer);
01046         break;
01047       case VTYPE_STRING:
01048         s = STRINGVALUE(ItemResult);
01049         slen = STRLEN(ItemResult);
01050         break;
01051       case VTYPE_ARRAY:
01052         sprintf(buffer,"ARRAY@#%08X",LONGVALUE(ItemResult));
01053         s = buffer;
01054         slen = strlen(buffer);
01055         break;
01056       }
01057 
01058     if( pFCO->mode[FileNumber] == 's' )
01059       HOOK_TCPSEND(THISSOCKET,s,slen,0);
01060     else
01061       while( slen -- )HOOK_PUTC(((int)*s++),THISFILEP);
01062 
01063     nItem = CDR(nItem);
01064     }
01065 
01066   if( pFCO->mode[FileNumber] != 's' &&
01067       fflush(THISFILEP) == EOF )ERROR(COMMAND_ERROR_PRINT_FAIL);
01068 
01069 #endif
01070 END
01071 
01072 COMMAND(FPRINTNL)
01073 #if NOTIMP_FPRINTNL
01074 NOTIMPLEMENTED;
01075 #else
01076 
01077 
01078   NODE nItem;
01079   long FileNumber;
01080   pFileCommandObject pFCO;
01081 
01082 
01083   INITIALIZE;
01084   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
01085 
01086   nItem = PARAMETERNODE;
01087   FileNumber = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(nItem)));
01088   ASSERTOKE;
01089   if( FileNumber < 1 || FileNumber > MAXFILES )RETURN;
01090   FileNumber --;
01091   if( ! pFCO->mode[FileNumber] )RETURN;
01092 
01093 
01094   if( pFCO->mode[FileNumber] == 's' )
01095     HOOK_TCPSEND(THISSOCKET,"\n",1,0);
01096   else{
01097     HOOK_PUTC('\n',THISFILEP);
01098     if( fflush(THISFILEP) == EOF )ERROR(COMMAND_ERROR_PRINT_FAIL);
01099     }
01100 
01101 #endif
01102 END
01103 #define NOCOMMAND(XXX) \
01104 COMMAND(XXX)\
01105 NOTIMPLEMENTED;\
01106 END
01107 
01108 #define FILE_FUN(XXX,yyy) \
01109 COMMAND(XXX)\
01110 \
01111   char *FileName;\
01112   VARIABLE Op;\
01113   long lRes;\
01114 \
01115   USE_CALLER_MORTALS;\
01116 \
01117   Op = _EVALUATEEXPRESSION(CAR(PARAMETERLIST));\
01118   ASSERTOKE;\
01119   if( memory_IsUndef(Op) ){\
01120     RESULT = NULL;\
01121     RETURN;\
01122     }\
01123 \
01124   Op = CONVERT2STRING(Op);\
01125 \
01126   FileName = ALLOC(STRLEN(Op)+1);\
01127   if( FileName == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);\
01128   memcpy(FileName,STRINGVALUE(Op),STRLEN(Op));\
01129   FileName[STRLEN(Op)] = (char)0;\
01130   lRes = yyy(FileName);\
01131   if( lRes == -1 ){\
01132     RESULT = NULL;\
01133     RETURN;\
01134     }\
01135 \
01136   RESULT = NEWMORTALLONG;\
01137   ASSERTNULL(RESULT)\
01138   LONGVALUE(RESULT) = lRes;\
01139   FREE(FileName);\
01140 \
01141 END
01142 
01143 #define FILE_BFUN(XXX,yyy) \
01144 COMMAND(XXX)\
01145 \
01146   char *FileName;\
01147   VARIABLE Op;\
01148   long lRes;\
01149 \
01150   USE_CALLER_MORTALS;\
01151 \
01152   Op = _EVALUATEEXPRESSION(CAR(PARAMETERLIST));\
01153   ASSERTOKE;\
01154   if( memory_IsUndef(Op) ){\
01155     RESULT = NULL;\
01156     RETURN;\
01157     }\
01158 \
01159   Op = CONVERT2STRING(Op);\
01160 \
01161   FileName = ALLOC(STRLEN(Op)+1);\
01162   if( FileName == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);\
01163   memcpy(FileName,STRINGVALUE(Op),STRLEN(Op));\
01164   FileName[STRLEN(Op)] = (char)0;\
01165   lRes = yyy(FileName);\
01166   RESULT = NEWMORTALLONG;\
01167   ASSERTNULL(RESULT)\
01168   LONGVALUE(RESULT) = lRes;\
01169   FREE(FileName);\
01170 \
01171 END
01172 
01182 #if NOTIMP_FILELEN
01183 NOCOMMAND(FILELEN)
01184 #else
01185 FILE_FUN(FILELEN,HOOK_SIZE)
01186 #endif
01187 
01205 #if NOTIMP_FTACCESS
01206 NOCOMMAND(FTACCESS)
01207 #else
01208 FILE_FUN(FTACCESS,HOOK_TIME_ACCESSED)
01209 #endif
01210 
01218 #if NOTIMP_FTMODIFY
01219 NOCOMMAND(FTMODIFY)
01220 #else
01221 FILE_FUN(FTMODIFY,HOOK_TIME_MODIFIED)
01222 #endif
01223 
01230 #if NOTIMP_FTCREATED
01231 NOCOMMAND(FTCREATED)
01232 #else
01233 FILE_FUN(FTCREATED,HOOK_TIME_CREATED)
01234 #endif
01235 
01242 #if NOTIMP_ISDIR
01243 NOCOMMAND(ISDIR)
01244 #else
01245 FILE_BFUN(ISDIR,HOOK_ISDIR)
01246 #endif
01247 
01254 #if NOTIMP_ISREG
01255 NOCOMMAND(ISREG)
01256 #else
01257 FILE_BFUN(ISREG,HOOK_ISREG)
01258 #endif
01259 
01266 #if NOTIMP_FILEXISTS
01267 NOCOMMAND(FILEXISTS)
01268 #else
01269 FILE_BFUN(FILEXISTS,HOOK_EXISTS)
01270 #endif
01271 
01296 COMMAND(FLOCK)
01297 #if NOTIMP_FLOCK
01298 NOTIMPLEMENTED;
01299 #else
01300 
01301 
01302   long FileNumber;
01303   char *ModeString;
01304   pFileCommandObject pFCO;
01305 
01306 
01307   INITIALIZE;
01308   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
01309 
01310   FileNumber = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
01311   ASSERTOKE;
01312   if( FileNumber < 1 || FileNumber > MAXFILES )RETURN;
01313   FileNumber --;
01314   if( ! pFCO->mode[FileNumber] || pFCO->mode[FileNumber] == 's' )RETURN;
01315 
01316   NEXTPARAMETER;
01317   ModeString = pEo->StringTable+pEo->CommandArray[_ActualNode-1].Parameter.CommandArgument.Argument.szStringValue;
01318 
01319   if( !stricmp(ModeString,"read") ){
01320     HOOK_FLOCK(THISFILEP,LOCK_SH);
01321     }else
01322   if( !stricmp(ModeString,"write") ){
01323     HOOK_FLOCK(THISFILEP,LOCK_EX);
01324     }else
01325   if( !stricmp(ModeString,"release") ){
01326     HOOK_FLOCK(THISFILEP,LOCK_UN);
01327     }else ERROR(COMMAND_ERROR_INVALID_LOCK);
01328 
01329 #endif
01330 END
01331 
01339 COMMAND(RLOCK)
01340 #if NOTIMP_RLOCK
01341 NOTIMPLEMENTED;
01342 #else
01343 
01344 
01345   long FileNumber,lFrom,lTo,lSwap;
01346   char *ModeString;
01347   pFileCommandObject pFCO;
01348 
01349   INITIALIZE;
01350   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
01351 
01352   FileNumber = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
01353   ASSERTOKE;
01354   if( FileNumber < 1 || FileNumber > MAXFILES )RETURN;
01355   FileNumber --;
01356   if( ! pFCO->mode[FileNumber] || pFCO->mode[FileNumber] == 's' )RETURN;
01357 
01358   NEXTPARAMETER;
01359   lFrom = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
01360   ASSERTOKE;
01361   if( lFrom < 0 )RETURN;
01362   NEXTPARAMETER;
01363   lTo   = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
01364   ASSERTOKE;
01365   if( lTo < 0 )RETURN;
01366   if( lFrom > lTo ){
01367     lSwap = lTo;
01368     lTo = lFrom;
01369     lFrom = lSwap;
01370     }
01371 
01372   NEXTPARAMETER;
01373   ModeString = pEo->StringTable+pEo->CommandArray[_ActualNode-1].Parameter.CommandArgument.Argument.szStringValue;
01374 
01375   if( !stricmp(ModeString,"read") ){
01376     HOOK_LOCK(THISFILEP,LOCK_SH,lFrom,(lTo-lFrom+1)*pFCO->RecordSize[FileNumber]);
01377     }else
01378   if( !stricmp(ModeString,"write") ){
01379     HOOK_LOCK(THISFILEP,LOCK_EX,lFrom,(lTo-lFrom+1)*pFCO->RecordSize[FileNumber]);
01380     }else
01381   if( !stricmp(ModeString,"release") ){
01382     HOOK_LOCK(THISFILEP,LOCK_UN,lFrom,(lTo-lFrom+1)*pFCO->RecordSize[FileNumber]);
01383     }else ERROR(COMMAND_ERROR_INVALID_LOCK);
01384 
01385 #endif
01386 END
01407 COMMAND(MKDIR)
01408 #if NOTIMP_MKDIR
01409 NOTIMPLEMENTED;
01410 #else
01411 
01412   VARIABLE Op;
01413   char *s;
01414 
01415   Op = CONVERT2STRING(EVALUATEEXPRESSION(PARAMETERNODE));
01416   ASSERTOKE;
01417   s = ALLOC(STRLEN(Op)+1);
01418   if( s == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
01419   memcpy(s,STRINGVALUE(Op),STRLEN(Op));
01420   s[STRLEN(Op)] = (char)0;
01421   if( HOOK_MAKEDIRECTORY(s) == -1 ){
01422     FREE(s);
01423     ERROR(COMMAND_ERROR_MKDIR_FAIL);
01424     }
01425   FREE(s);
01426 #endif
01427 END
01428 
01439 COMMAND(DELETE)
01440 #if NOTIMP_DELETE
01441 NOTIMPLEMENTED;
01442 #else
01443 
01444   VARIABLE Op;
01445   char *s;
01446   int iResult;
01447 
01448   Op = CONVERT2STRING(EVALUATEEXPRESSION(PARAMETERNODE));
01449   s = ALLOC(STRLEN(Op)+1);
01450   ASSERTOKE;
01451   if( s == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
01452   memcpy(s,STRINGVALUE(Op),STRLEN(Op));
01453   s[STRLEN(Op)] = (char)0;
01454   if( ! HOOK_EXISTS(s) ){
01455     FREE(s);
01456     RETURN;
01457     }
01458   if( HOOK_ISDIR(s) ){
01459     iResult = HOOK_RMDIR(s);
01460     FREE(s);
01461     if( iResult == -1 )ERROR(COMMAND_ERROR_DELETE_FAIL);
01462     RETURN;
01463     }
01464   iResult = HOOK_REMOVE(s);
01465   FREE(s);
01466   if( iResult == -1 )ERROR(COMMAND_ERROR_DELETE_FAIL);
01467   RETURN;
01468 
01469 #endif
01470 END
01471 
01484 COMMAND(FCOPY)
01485 #if NOTIMP_FCOPY
01486 NOTIMPLEMENTED;
01487 #else
01488 
01489   VARIABLE Op1,Op2;
01490   char *sfile,*dfile;
01491   FILE *fs,*fd;
01492   int ch;
01493   long i,LastDSPos;
01494 
01495   Op1 = CONVERT2STRING(EVALUATEEXPRESSION(PARAMETERNODE));
01496   ASSERTOKE;
01497   CONVERT2ZCHAR(Op1,sfile);
01498   /* the file that we copy should exist */
01499   if( ! HOOK_EXISTS(sfile) ){
01500     FREE(sfile);
01501     RETURN;
01502     }
01503   NEXTPARAMETER;
01504   Op2 = CONVERT2STRING(EVALUATEEXPRESSION(PARAMETERNODE));
01505   ASSERTOKE;
01506   CONVERT2ZCHAR(Op2,dfile);
01507   fs = HOOK_FOPEN(sfile,"rb");
01508   if( fs == NULL ){
01509     FREE(sfile);
01510     FREE(dfile);
01511     ERROR(COMMAND_ERROR_FILE_READ);
01512     }
01513 
01514   /* if the file is going into a directory that does not exist yet then try to create the directory */
01515   LastDSPos = 0;
01516   for( i=0 ; dfile[i] ; i++ )
01517 #ifdef __MACOS__
01518     if( dfile[i] == ':' )LastDSPos = i;
01519 #else
01520     if( dfile[i] == '/' || dfile[i] == '\\' )LastDSPos = i;
01521 #endif
01522   if( LastDSPos ){
01523     i = dfile[LastDSPos];
01524     dfile[LastDSPos] = (char)0;
01525     HOOK_MAKEDIRECTORY(dfile);
01526     dfile[LastDSPos] = (char)i;
01527     }
01528 
01529   fd = HOOK_FOPEN(dfile,"wb");
01530   if( fd == NULL ){
01531     HOOK_FCLOSE(fs);
01532     FREE(sfile);
01533     FREE(dfile);
01534     ERROR(COMMAND_ERROR_FILE_WRITE);
01535     }
01536   while( (ch=HOOK_FGETC(fs)) != EOF ){
01537     HOOK_PUTC(ch,fd);
01538     }
01539   HOOK_FCLOSE(fs);
01540   HOOK_FCLOSE(fd);
01541   FREE(sfile);
01542   FREE(dfile);
01543   RETURN;
01544 #endif
01545 END
01546 
01557 COMMAND(NAME)
01558 #if NOTIMP_NAME
01559 NOTIMPLEMENTED;
01560 #else
01561 
01562   VARIABLE Op1,Op2;
01563   char *sfile,*dfile;
01564 
01565   Op1 = CONVERT2STRING(EVALUATEEXPRESSION(PARAMETERNODE));
01566   ASSERTOKE;
01567   CONVERT2ZCHAR(Op1,sfile);
01568   /* the file that we copy should exist */
01569   if( ! HOOK_EXISTS(sfile) ){
01570     FREE(sfile);
01571     RETURN;
01572     }
01573   NEXTPARAMETER;
01574   Op2 = CONVERT2STRING(EVALUATEEXPRESSION(PARAMETERNODE));
01575   ASSERTOKE;
01576   CONVERT2ZCHAR(Op2,dfile);
01577 
01578   rename(sfile,dfile);
01579 
01580   FREE(sfile);
01581   FREE(dfile);
01582   RETURN;
01583 #endif
01584 END
01585 
01596 COMMAND(DELETEF)
01597 #if NOTIMP_DELETEF
01598 NOTIMPLEMENTED;
01599 #else
01600 
01601   VARIABLE Op;
01602   char *s;
01603   int iResult;
01604 
01605   Op = CONVERT2STRING(EVALUATEEXPRESSION(PARAMETERNODE));
01606   ASSERTOKE;
01607   s = ALLOC(STRLEN(Op)+1);
01608   if( s == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
01609   memcpy(s,STRINGVALUE(Op),STRLEN(Op));
01610   s[STRLEN(Op)] = (char)0;
01611   if( ! HOOK_EXISTS(s) ){
01612     FREE(s);
01613     RETURN;
01614     }
01615   if( ! HOOK_ISDIR(s) ){
01616     iResult = HOOK_REMOVE(s);
01617     FREE(s);
01618     if( iResult == -1 )ERROR(COMMAND_ERROR_DELETE_FAIL);
01619     RETURN;
01620     }
01621 
01622   /* Delete the files recursively inside the directory. */
01623   iResult = HOOK_DELTREE(s);
01624   FREE(s);
01625   if( iResult == -1 )ERROR(COMMAND_ERROR_DELETE_FAIL);
01626   RETURN;
01627 
01628 #endif
01629 END
01630 
01631 #define MAXDIRS 512
01632 
01633 /* A DirList contains the file names.
01634 
01635    The field cbFileName points to an array.
01636    Each element of the array contains the length of a file name.
01637 
01638    SortValue is an array that stores file size, creation date or
01639    other parameter according to the sort condition.
01640 
01641    ppszFileName points to an array of char * each pointing to a
01642    file name. This array is altered during sort.
01643 
01644    cFileNames is the number of file names in the list.
01645 
01646    FileIndex is the index to the cbFileName array for the
01647    current file name during file iterations.
01648 
01649 */
01650 typedef struct _DirList {
01651   unsigned long *cbFileName; /* file name length */
01652   unsigned long *SortValue;  /* sort value or string offset */
01653   char **ppszFileName;       /* file name */
01654   unsigned long cFileNames;  /* number of file names */
01655   unsigned long FileIndex;   /* current file index */
01656   } DirList, *pDirList;
01657 
01658 #define FILES_INCREMENT 10
01659 static int store_file_name(pExecuteObject pEo,
01660                            pDirList p,
01661                            char *buffer,
01662                            unsigned long ThisSortValue
01663 
01664   ){
01665   unsigned long ulNewSize;
01666   unsigned long *plNewCbFileName,*NewSortValue;
01667   char **ppszNewppszFileName;
01668   unsigned long i;
01669 
01670   /* first of all check that there is enough space to store the file name on the current index location. */
01671   if( p->FileIndex >= (ulNewSize = p->cFileNames) ){
01672     while( p->FileIndex >= ulNewSize )/* this while is redundant unless there is a programming error somwhere else */
01673       ulNewSize += FILES_INCREMENT;
01674     plNewCbFileName = ALLOC( ulNewSize * sizeof(long) );
01675     if( plNewCbFileName == NULL )return 1;
01676     NewSortValue = ALLOC( ulNewSize * sizeof(long));
01677     if( NewSortValue == NULL )return 1;
01678     ppszNewppszFileName = ALLOC( ulNewSize * sizeof(char *));
01679     if( ppszNewppszFileName == NULL )return 1;
01680     for( i=0 ; i < p->cFileNames ; i++ ){
01681        plNewCbFileName[i] = p->cbFileName[i];
01682        NewSortValue[i] = p->SortValue[i];
01683        ppszNewppszFileName[i] = p->ppszFileName[i];
01684        }
01685     if( p->cbFileName )FREE(p->cbFileName);
01686     if( p->SortValue )FREE(p->SortValue);
01687     if( p->ppszFileName )FREE(p->ppszFileName);
01688     p->cbFileName = plNewCbFileName;
01689     p->SortValue = NewSortValue;
01690     p->ppszFileName = ppszNewppszFileName;
01691     p->cFileNames = ulNewSize;
01692     }
01693 
01694   if( (p->ppszFileName[p->FileIndex] = ALLOC( (p->cbFileName[p->FileIndex] = strlen(buffer)) )) == NULL )
01695     return 1;
01696   memcpy(p->ppszFileName[p->FileIndex],buffer,p->cbFileName[p->FileIndex]);
01697   p->SortValue[p->FileIndex] = ThisSortValue;
01698   p->FileIndex++;
01699   return 0;
01700   }
01701 
01702 typedef struct _DirCommandObject {
01703   pDirList dp[MAXDIRS];
01704   } DirCommandObject, *pDirCommandObject;
01705 
01706 static void close_directory_list(pExecuteObject pEo,
01707                                  unsigned long i
01708   ){
01709   pDirCommandObject pDCO;
01710   unsigned long j;
01711 
01712   pDCO = (pDirCommandObject)PARAMPTR(CMD_OPENDIR);
01713   if( pDCO == NULL )return;
01714 
01715   for( j=0 ; j<pDCO->dp[i]->cFileNames ; j++ )
01716      FREE(pDCO->dp[i]->ppszFileName[j]);
01717   /* the following two pointers may be null if the directory list contained no file name*/
01718   if( pDCO->dp[i]->cbFileName )FREE( pDCO->dp[i]->cbFileName);
01719   if( pDCO->dp[i]->ppszFileName )FREE( pDCO->dp[i]->ppszFileName);
01720   /* this should never be null when we get here */
01721   if( pDCO->dp[i] )FREE( pDCO->dp[i]);
01722   pDCO->dp[i] = NULL;
01723   return;
01724   }
01725 
01726 static void close_all_dirs(pExecuteObject pEo){
01727   pDirCommandObject pDCO;
01728   long i;
01729 
01730   pDCO = (pDirCommandObject)PARAMPTR(CMD_OPENDIR);
01731   if( pDCO == NULL )return;
01732   for( i = 0 ; i < MAXDIRS ; i++ )
01733     if( pDCO->dp[i] )
01734       close_directory_list(pEo,i);
01735   }
01736 
01737 static int initdir(pExecuteObject pEo){
01738 #define INITDIR initdir(pEo)
01739   pDirCommandObject pDCO;
01740   int i;
01741 
01742   /* initialize only once */
01743   if( PARAMPTR(CMD_OPENDIR) )return 0;
01744 
01745   PARAMPTR(CMD_OPENDIR) = ALLOC(sizeof(DirCommandObject));
01746   if( PARAMPTR(CMD_OPENDIR) == NULL )return COMMAND_ERROR_MEMORY_LOW;
01747 
01748   pDCO = (pDirCommandObject)PARAMPTR(CMD_OPENDIR);
01749   for( i=0 ; i < MAXDIRS ; i++ )
01750     pDCO->dp[i] = NULL;
01751 
01752   FINALPTR(CMD_OPENDIR) = close_all_dirs;
01753   return 0;
01754   }
01755 
01756 
01757 #define COLLECT_DIRS   0x0001 /* collect directories as well */
01758 #define COLLECT_DOTS   0x0002 /* collect the dot directories */
01759 #define COLLECT_RECU   0x0004 /* collect recursively */
01760 #define SORTBY_SIZE    0x0008 /* sort by file size */
01761 #define SORTBY_CRETI   0x0010 /* sort by creation time */
01762 #define SORTBY_ACCTI   0x0020 /* sort by access time */
01763 #define SORTBY_MODTI   0x0040 /* sort by modification time */
01764 #define SORTBY_NAME    0x0080 /* sort by name (no directory part is compared) */
01765 #define SORTBY_FNAME   0x0100 /* sort by full name */
01766 #define COLLECT_FULLP  0x0200 /* collect and return "full" path names including the original directory name in
01767                                  each file name retuned (can directly be used in file handling statements */
01768 #define SORTBY_DESCEN  0x0400 /* sort descending order */
01769 
01770 #define MAX_FNLEN 1024
01771 
01772 /* This function recursively collects
01773 */
01774 static int collect_dirs_r(pExecuteObject pEo,
01775                           char * buffer,
01776                           unsigned long fAction,
01777                           pDirList pThisDirList,
01778                           char *pattern,
01779                           unsigned long StartCharIndex
01780   ){
01781   tDIR DL;
01782   DIR *pDL;
01783   struct dirent *pD;
01784   int dirlen;
01785 
01786   unsigned long sL,pL,i;
01787   unsigned long cArraySize;
01788   pPatternParam pLastResult;
01789   int iError;
01790   unsigned long ulSortValue;
01791 
01792   pLastResult = (pPatternParam)PARAMPTR(CMD_LIKEOP);
01793 
01794   dirlen=strlen(buffer);
01795 #ifdef __MACOS__
01796   if( buffer[dirlen-1] != ':' ){
01797     dirlen++;
01798     if( dirlen >= MAX_FNLEN )return -1;
01799     strcpy(buffer+dirlen-1,":");
01800     }
01801 #else
01802   if( buffer[dirlen-1] != '/' ){
01803     dirlen++;
01804     if( dirlen >= MAX_FNLEN )return -1;
01805     strcpy(buffer+dirlen-1,"/");
01806     }
01807 #endif
01808   pDL = HOOK_OPENDIR(buffer,&DL);
01809   if( pDL == NULL )return -1;
01810   while( pD = HOOK_READDIR(pDL) ){
01811     /* skip . and .. directories */
01812     if( pD->d_name[0] == '.' && 
01813        ( pD->d_name[1] == (char)0 ||
01814          ( pD->d_name[1] == '.' && pD->d_name[2] == (char)0 ) ) ){
01815       if( fAction&COLLECT_DOTS ){
01816         if( dirlen+strlen(pD->d_name) >= MAX_FNLEN )return -1;
01817         strcpy(buffer+dirlen,pD->d_name);
01818         if( fAction & SORTBY_SIZE )ulSortValue = HOOK_SIZE(buffer); else
01819         if( fAction & SORTBY_CRETI )ulSortValue = HOOK_TIME_CREATED(buffer); else
01820         if( fAction & SORTBY_MODTI )ulSortValue = HOOK_TIME_MODIFIED(buffer); else
01821         if( fAction & SORTBY_ACCTI )ulSortValue = HOOK_TIME_ACCESSED(buffer); else
01822         if( fAction & SORTBY_NAME  )ulSortValue = dirlen - StartCharIndex; else
01823         ulSortValue = 0; /* SORTBY_FNAME */
01824         if( store_file_name(pEo,pThisDirList,buffer+StartCharIndex,ulSortValue) )return -1;
01825         }
01826       continue;
01827       }
01828     if( dirlen+(sL=strlen(pD->d_name)) >= MAX_FNLEN )return -1;
01829     strcpy(buffer+dirlen,pD->d_name);
01830     if( *pattern ){
01831       pL = strlen(pattern);
01832       cArraySize = match_count(pattern,pL);
01833       if( cArraySize > pLastResult->cArraySize ){
01834         if( pLastResult->pcbParameterArray )FREE(pLastResult->pcbParameterArray);
01835         if( pLastResult->ParameterArray)FREE(pLastResult->ParameterArray);
01836         pLastResult->cArraySize = 0;
01837         pLastResult->pcbParameterArray = ALLOC(cArraySize*sizeof(unsigned long));
01838         if( pLastResult->pcbParameterArray == NULL )return -1;
01839         pLastResult->ParameterArray    = ALLOC(cArraySize*sizeof(char *));
01840         if( pLastResult->ParameterArray == NULL ){
01841           FREE(pLastResult->pcbParameterArray);
01842           pLastResult->pcbParameterArray = NULL;
01843           return -1;
01844           }
01845         pLastResult->cArraySize = cArraySize;
01846         }else{
01847         /* If the array is long enough then delete the previous result otherwise
01848            fake data may remain in it and it may cause trouble. */
01849         for( i=0 ; i < pLastResult->cArraySize ; i++ ){
01850           pLastResult->pcbParameterArray[i] = 0;
01851           pLastResult->ParameterArray[i] = NULL;
01852           }
01853         }
01854       pLastResult->cAArraySize = cArraySize;
01855 
01856       if( pLastResult->cbBufferSize < sL ){
01857         pLastResult->cbBufferSize = 0;
01858         if( pLastResult->pszBuffer )FREE(pLastResult->pszBuffer);
01859         pLastResult->pszBuffer = ALLOC(sL*sizeof(char));
01860         if( pLastResult->pszBuffer == NULL )return -1;
01861         pLastResult->cbBufferSize = sL;
01862         }
01863 
01864       iError = match_match(pattern,
01865                            pL,
01866                            buffer+dirlen,
01867                            sL,
01868                            pLastResult->ParameterArray,
01869                            pLastResult->pcbParameterArray,
01870                            pLastResult->pszBuffer,
01871                            pLastResult->cArraySize,
01872                            pLastResult->cbBufferSize,
01873 #ifdef WIN32
01874                            0,
01875 #else
01876                            !(OPTION("compare")&1),
01877 #endif
01878                            pLastResult->pThisMatchSets,
01879                            &(pLastResult->iMatches));
01880       }
01881     if( (!*pattern) || pLastResult->iMatches ){
01882       if( fAction & SORTBY_SIZE )ulSortValue = HOOK_SIZE(buffer); else
01883       if( fAction & SORTBY_CRETI )ulSortValue = HOOK_TIME_CREATED(buffer); else
01884       if( fAction & SORTBY_MODTI )ulSortValue = HOOK_TIME_MODIFIED(buffer); else
01885       if( fAction & SORTBY_ACCTI )ulSortValue = HOOK_TIME_ACCESSED(buffer); else
01886       if( fAction & SORTBY_NAME  )ulSortValue = dirlen - StartCharIndex; else
01887       ulSortValue = 0;
01888       if( (fAction & COLLECT_DIRS) || (!HOOK_ISDIR(buffer)) )
01889         store_file_name(pEo,pThisDirList,buffer+StartCharIndex,ulSortValue);
01890       }
01891     pLastResult->iMatches = 0; /* no joker() after file pattern match */
01892     if( HOOK_ISDIR(buffer) && (fAction & COLLECT_RECU) )
01893       collect_dirs_r(pEo,buffer,fAction,pThisDirList,pattern,StartCharIndex);
01894     }
01895   HOOK_CLOSEDIR(pDL);
01896   dirlen--;
01897   buffer[dirlen] = (char)0;
01898   return 0;
01899   }
01900 
01901 static int collect_dirs(pExecuteObject pEo,
01902                         unsigned long fAction,
01903                         pDirList pThisDirList,
01904                         char *Directory,
01905                         unsigned long cDirectory,
01906                         char *pattern,
01907                         unsigned long c_pattern
01908   ){
01909   char buffer[MAX_FNLEN];
01910   char puffer[MAX_FNLEN];
01911   unsigned long StartCharIndex;
01912 
01913   if( initialize_like(pEo) )return -1;
01914   memcpy(buffer,Directory,cDirectory);
01915   buffer[cDirectory] = (char)0;
01916 #ifdef __MACOS__
01917   if( buffer[cDirectory-1] != ':' ){
01918     cDirectory++;
01919     if( cDirectory >= MAX_FNLEN )return -1;
01920     strcpy(buffer+cDirectory-1,":");
01921     }
01922 #else
01923   if( buffer[cDirectory-1] != '/' ){
01924     cDirectory++;
01925     if( cDirectory >= MAX_FNLEN )return -1;
01926     strcpy(buffer+cDirectory-1,"/");
01927     }
01928 #endif
01929   if( pattern )
01930     memcpy(puffer,pattern,c_pattern);
01931   puffer[c_pattern] = (char)0;
01932 
01933   StartCharIndex = strlen(buffer);
01934   if( fAction & COLLECT_FULLP )StartCharIndex = 0;
01935   if( collect_dirs_r(pEo,buffer,fAction,pThisDirList,puffer,StartCharIndex) == -1 )return -1;
01936   pThisDirList->cFileNames = pThisDirList->FileIndex;
01937   pThisDirList->FileIndex = 0;
01938   return 0;
01939   }
01940 
01941 static int sort_dirs(pExecuteObject pEo,
01942                         unsigned long fAction,
01943                         pDirList p
01944   ){
01945   unsigned long i,j;
01946   unsigned long lSwap;
01947   char *pszSwap;
01948   unsigned long CompareLength,Leni,Lenj;
01949   int CompareSult;
01950 
01951 #define SWAP do{\
01952                 lSwap = p->cbFileName[i];\
01953                 p->cbFileName[i] = p->cbFileName[j];\
01954                 p->cbFileName[j] = lSwap;\
01955                 lSwap = p->SortValue[i];\
01956                 p->SortValue[i] = p->SortValue[j];\
01957                 p->SortValue[j] = lSwap;\
01958                 pszSwap = p->ppszFileName[i];\
01959                 p->ppszFileName[i] = p->ppszFileName[j];\
01960                 p->ppszFileName[j] = pszSwap;\
01961                 }while(0)
01962 
01963   /* if there is nothing to sort by */
01964   if( !(fAction & ( SORTBY_SIZE | SORTBY_CRETI | SORTBY_ACCTI | SORTBY_MODTI | SORTBY_NAME | SORTBY_FNAME)) )
01965     return 0;
01966 
01967   if( fAction & (SORTBY_NAME | SORTBY_FNAME) ){
01968     /* string type of comparision */
01969     for( i=1 ; i < p->cFileNames ; i++ )
01970      for( j=0 ; j < i ; j++ ){
01971        CompareLength = Leni = p->cbFileName[i] - p->SortValue[i];
01972        if( CompareLength > (Lenj=p->cbFileName[j] - p->SortValue[j]) )
01973          CompareLength = Lenj;
01974        CompareSult = memcmp(p->ppszFileName[i]+p->SortValue[i],p->ppszFileName[j]+p->SortValue[j],CompareLength);
01975        CompareSult = CompareSult > 0 || (CompareSult == 0 && Leni > Lenj);
01976        if( fAction & SORTBY_DESCEN )CompareSult = !CompareSult;
01977        if( CompareSult )
01978          SWAP;
01979        }
01980     }else{
01981     /* numeric comparision based on collected value */
01982     for( i=1 ; i < p->cFileNames ; i++ )
01983      for( j=0 ; j < i ; j++ )
01984        if( (fAction & SORTBY_DESCEN) ? p->SortValue[i] < p->SortValue[j] : p->SortValue[i] > p->SortValue[j] )
01985          SWAP;
01986     }
01987   return 0;
01988   }
01989 
02035 COMMAND(OPENDIR)
02036 #if NOTIMP_OPENDIR
02037 NOTIMPLEMENTED;
02038 #else
02039 
02040   long DirNumber;
02041   char *DirName;
02042   unsigned long i;
02043   pDirCommandObject pDCO;
02044   VARIABLE vDirName,vPattern,vDirNumber,vOption;
02045   unsigned long fAction;
02046 
02047   INITDIR;
02048   pDCO = (pDirCommandObject)PARAMPTR(CMD_OPENDIR);
02049 
02050   /* get the directory name */
02051   vDirName = CONVERT2STRING(_EVALUATEEXPRESSION(PARAMETERNODE));
02052   ASSERTOKE;
02053   NEXTPARAMETER;
02054   vPattern = CONVERT2STRING(_EVALUATEEXPRESSION(PARAMETERNODE));
02055   ASSERTOKE;
02056   NEXTPARAMETER;
02057   vOption = CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE));
02058   ASSERTOKE;
02059   NEXTPARAMETER;
02060   vDirNumber = _EVALUATEEXPRESSION(PARAMETERNODE);
02061   ASSERTOKE;
02062   if( memory_IsUndef(vDirNumber) )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
02063   if( TYPE(vDirNumber) == VTYPE_LONG && LONGVALUE(vDirNumber) == 0 ){/* we have to automatically allocate the file number */
02064     for( i = 1 ; i < MAXFILES ; i++ )
02065       if( pDCO->dp[i] == NULL )break;
02066     if( i >= MAXFILES )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
02067     LONGVALUE(vDirNumber) = i;
02068     }
02069   DirNumber = LONGVALUE(CONVERT2LONG(vDirNumber));
02070 
02071   if( DirNumber <1 || DirNumber >= MAXDIRS )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
02072   if( pDCO->dp[DirNumber] )ERROR(COMMAND_ERROR_FILE_NUMBER_IS_USED);
02073 
02074   /* copy the dir name to DirName zchar terminated. */
02075   if( memory_IsUndef(vDirName) )ERROR(COMMAND_ERROR_INV_DNAME);
02076   SECUREFILE(vDirName)
02077   CONVERT2ZCHAR(vDirName,DirName);
02078 
02079   pDCO->dp[DirNumber] = ALLOC( sizeof(DirList) );
02080   if( pDCO->dp[DirNumber] == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
02081   pDCO->dp[DirNumber]->cFileNames = 0;
02082   pDCO->dp[DirNumber]->FileIndex  = 0;
02083   pDCO->dp[DirNumber]->cbFileName = NULL;
02084   pDCO->dp[DirNumber]->SortValue = NULL;
02085   pDCO->dp[DirNumber]->ppszFileName = NULL;
02086 
02087   if( memory_IsUndef(vOption) )ERROR(COMMAND_ERROR_INV_DO_OPTION);
02088   fAction = ~ (GETLONGVALUE(vOption));
02089 
02090 #define SORTBY_SIZE    0x0008 /* sort by file size */
02091 #define SORTBY_CRETI   0x0010 /* sort by creation time */
02092 #define SORTBY_ACCTI   0x0020 /* sort by access time */
02093 #define SORTBY_MODTI   0x0040 /* sort by modification time */
02094 #define SORTBY_NAME    0x0080 /* sort by name (no directory part is compared) */
02095 #define SORTBY_FNAME   0x0100 /* sort by full name */
02096 
02097   /* If the user specifies more than one sorting criuteria, we have to correct it,
02098      because the underlying layers assume that only one bit is set. Former version
02099      crashed when open directory option was sloppyly set to 0. */
02100   if( fAction & SORTBY_SIZE  )
02101     fAction &= ~(    0      |SORTBY_CRETI|SORTBY_ACCTI|SORTBY_MODTI|SORTBY_NAME|SORTBY_FNAME); else
02102   if( fAction & SORTBY_CRETI )
02103     fAction &= ~(SORTBY_SIZE|       0    |SORTBY_ACCTI|SORTBY_MODTI|SORTBY_NAME|SORTBY_FNAME); else
02104   if( fAction & SORTBY_ACCTI )
02105     fAction &= ~(SORTBY_SIZE|SORTBY_CRETI|      0     |SORTBY_MODTI|SORTBY_NAME|SORTBY_FNAME); else
02106   if( fAction & SORTBY_MODTI )
02107     fAction &= ~(SORTBY_SIZE|SORTBY_CRETI|SORTBY_ACCTI|      0     |SORTBY_NAME|SORTBY_FNAME); else
02108   if( fAction & SORTBY_NAME  )
02109     fAction &= ~(SORTBY_SIZE|SORTBY_CRETI|SORTBY_ACCTI|SORTBY_MODTI|      0    |SORTBY_FNAME); else
02110   if( fAction & SORTBY_FNAME )
02111     fAction &= ~(SORTBY_SIZE|SORTBY_CRETI|SORTBY_ACCTI|SORTBY_MODTI|SORTBY_NAME|      0     );
02112 
02113   if( collect_dirs(pEo,
02114                    fAction,
02115                    pDCO->dp[DirNumber],
02116                    STRINGVALUE(vDirName),
02117                    STRLEN(vDirName),
02118                    vPattern ? STRINGVALUE(vPattern) : NULL ,
02119                    vPattern ? STRLEN(vPattern) : 0 ) == -1 ){
02120     close_directory_list(pEo,DirNumber);
02121     ERROR(COMMAND_ERROR_DIR_NO_OPEN); 
02122     }
02123   sort_dirs(pEo,
02124             fAction,
02125             pDCO->dp[DirNumber]);
02126 #endif
02127 END
02128 
02139 COMMAND(NEXTFILE)
02140 #if NOTIMP_NEXTFILE
02141 NOTIMPLEMENTED;
02142 #else
02143 
02144   VARIABLE Op1;
02145   pDirCommandObject pDCO;
02146   unsigned long DirNumber;
02147 
02148   INITDIR;
02149   pDCO = (pDirCommandObject)PARAMPTR(CMD_OPENDIR);
02150 
02151   /* this is an operator and not a command, therefore we do not have our own mortal list */
02152   USE_CALLER_MORTALS;
02153 
02154   Op1 = CONVERT2LONG(EVALUATEEXPRESSION(CAR(PARAMETERLIST)));
02155   ASSERTOKE;
02156   if( memory_IsUndef(Op1) ){
02157     RESULT = NULL;
02158     RETURN;
02159     }
02160   DirNumber = LONGVALUE(Op1);
02161   if( DirNumber <1 || DirNumber >= MAXDIRS )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
02162 
02163   if( pDCO->dp[DirNumber]->FileIndex >= pDCO->dp[DirNumber]->cFileNames ){
02164     RESULT = NULL;
02165     RETURN;
02166     }
02167 
02168   RESULT = NEWMORTALSTRING(pDCO->dp[DirNumber]->cbFileName[pDCO->dp[DirNumber]->FileIndex]);
02169   ASSERTNULL(RESULT)
02170   memcpy(STRINGVALUE(RESULT),pDCO->dp[DirNumber]->ppszFileName[pDCO->dp[DirNumber]->FileIndex],
02171          (STRLEN(RESULT)=pDCO->dp[DirNumber]->cbFileName[pDCO->dp[DirNumber]->FileIndex]));
02172   pDCO->dp[DirNumber]->FileIndex++;
02173 #endif
02174 END
02175 
02186 COMMAND(EODFUN)
02187 #if NOTIMP_EODFUN
02188 NOTIMPLEMENTED;
02189 #else
02190 
02191   VARIABLE Op1;
02192   pDirCommandObject pDCO;
02193   unsigned long DirNumber;
02194 
02195   INITDIR;
02196   pDCO = (pDirCommandObject)PARAMPTR(CMD_OPENDIR);
02197 
02198   /* this is an operator and not a command, therefore we do not have our own mortal list */
02199   USE_CALLER_MORTALS;
02200 
02201   Op1 = CONVERT2LONG(EVALUATEEXPRESSION(CAR(PARAMETERLIST)));
02202   ASSERTOKE;
02203   if( memory_IsUndef(Op1) ){
02204     RESULT = NULL;
02205     RETURN;
02206     }
02207   DirNumber = LONGVALUE(Op1);
02208   if( DirNumber <1 || DirNumber >= MAXDIRS )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
02209   if( pDCO->dp[DirNumber]->FileIndex >= pDCO->dp[DirNumber]->cFileNames ){
02210     RESULT = NEWMORTALLONG;
02211     ASSERTNULL(RESULT)
02212     LONGVALUE(RESULT) = -1;
02213     RETURN;
02214     }
02215   RESULT = NEWMORTALLONG;
02216   ASSERTNULL(RESULT)
02217   LONGVALUE(RESULT) = 0;
02218 #endif
02219 END
02220 
02231 COMMAND(RESETDIR)
02232 #if NOTIMP_RESETDIR
02233 NOTIMPLEMENTED;
02234 #else
02235 
02236   VARIABLE Op1;
02237   pDirCommandObject pDCO;
02238   unsigned long DirNumber;
02239 
02240   INITDIR;
02241   pDCO = (pDirCommandObject)PARAMPTR(CMD_OPENDIR);
02242 
02243   Op1 = CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE));
02244   ASSERTOKE;
02245   if( memory_IsUndef(Op1) ){
02246     RESULT = NULL;
02247     RETURN;
02248     }
02249   DirNumber = LONGVALUE(Op1);
02250   if( DirNumber <1 || DirNumber >= MAXDIRS )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
02251   pDCO->dp[DirNumber]->FileIndex = 0;
02252 #endif
02253 END
02254 
02264 COMMAND(CLOSEDIR)
02265 #if NOTIMP_CLOSEDIR
02266 NOTIMPLEMENTED;
02267 #else
02268 
02269   VARIABLE Op1;
02270   pDirCommandObject pDCO;
02271   unsigned long DirNumber;
02272 
02273   INITDIR;
02274   pDCO = (pDirCommandObject)PARAMPTR(CMD_OPENDIR);
02275 
02276   Op1 = CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE));
02277   ASSERTOKE;
02278   if( memory_IsUndef(Op1) ){
02279     RESULT = NULL;
02280     RETURN;
02281     }
02282   DirNumber = LONGVALUE(Op1);
02283   if( DirNumber <1 || DirNumber >= MAXDIRS )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
02284   close_directory_list(pEo,DirNumber);
02285 #endif
02286 END
02287 
02312 COMMAND(SLEEP)
02313 #if NOTIMP_SLEEP
02314 NOTIMPLEMENTED;
02315 #else
02316 
02317   VARIABLE Op1;
02318 
02319   Op1 = CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE));
02320   ASSERTOKE;
02321   if( ! memory_IsUndef(Op1) )
02322     sys_sleep(LONGVALUE(Op1));
02323 
02324 #endif
02325 END
02326 
02340 COMMAND(PAUSE)
02341 #if NOTIMP_PAUSE
02342 NOTIMPLEMENTED;
02343 #else
02344 NOTIMPLEMENTED;
02345 #endif
02346 END
02347 
02355 COMMAND(HOSTNAME)
02356 #if NOTIMP_HOSTNAME
02357 NOTIMPLEMENTED;
02358 #else
02359 
02360   char *pszBuffer;
02361   long cbBuffer;
02362   int err;
02363 
02364   cbBuffer = 256;
02365   pszBuffer = ALLOC(cbBuffer);
02366   err = HOOK_GETHOSTNAME(pszBuffer,cbBuffer);
02367   if( err == 0 ){
02368     cbBuffer = strlen(pszBuffer);
02369     RESULT = NEWMORTALSTRING(cbBuffer);
02370     ASSERTNULL(RESULT)
02371     memcpy(STRINGVALUE(RESULT),pszBuffer,cbBuffer);
02372     }else RESULT = NULL;
02373 #endif
02374 END
02375 
02383 COMMAND(CURDIR)
02384 #if NOTIMP_CURDIR
02385 NOTIMPLEMENTED;
02386 #else
02387 
02388  char *Buffer;
02389  long cBuffer;
02390 
02391   USE_CALLER_MORTALS;
02392 
02393   cBuffer = 256;
02394   Buffer = ALLOC(cBuffer);
02395   while( HOOK_CURDIR(Buffer,cBuffer) == -1 ){
02396     FREE(Buffer);
02397     cBuffer += 256;
02398     if( cBuffer > 1024 )ERROR(COMMAND_ERROR_CURDIR);
02399     Buffer = ALLOC(cBuffer);
02400     }
02401   cBuffer = strlen(Buffer);
02402   RESULT = NEWMORTALSTRING(cBuffer);
02403   ASSERTNULL(RESULT)
02404 
02405   memcpy(STRINGVALUE(RESULT),Buffer,cBuffer);
02406 #endif
02407 END
02408 
02422 COMMAND(CHDIR)
02423 #if NOTIMP_CHDIR
02424 NOTIMPLEMENTED;
02425 #else
02426 
02427   VARIABLE Op;
02428   char *Buffer;
02429   int i;
02430 
02431   Op = CONVERT2STRING(_EVALUATEEXPRESSION(PARAMETERNODE));
02432   ASSERTOKE;
02433   if( memory_IsUndef(Op) )ERROR(COMMAND_ERROR_UNDEF_DIR);
02434 
02435   SECUREFILE(Op)
02436   CONVERT2ZCHAR(Op,Buffer);
02437 
02438   i = HOOK_CHDIR(Buffer);
02439   FREE(Buffer);
02440   if( i )ERROR(COMMAND_ERROR_CHDIR);
02441   
02442 #endif
02443 END
02444 
02467 COMMAND(SETFILE)
02468 #if NOTIMP_SETFILE
02469 NOTIMPLEMENTED;
02470 #else
02471 
02472   VARIABLE vAttribute,vFile;
02473   long iErrorC;
02474   char *pszAttribute,*pszFile,*pszAttributeSymbol;
02475 
02476   vFile = CONVERT2STRING(_EVALUATEEXPRESSION(PARAMETERNODE));
02477   ASSERTOKE;
02478   NEXTPARAMETER;
02479   pszAttributeSymbol = pEo->StringTable+pEo->CommandArray[_ActualNode-1].Parameter.CommandArgument.Argument.szStringValue;
02480   NEXTPARAMETER;
02481   vAttribute = EVALUATEEXPRESSION(PARAMETERNODE);
02482   ASSERTOKE;
02483 
02484   if( memory_IsUndef(vAttribute) )ERROR(COMMAND_ERROR_SETFILE_INVALID_ATTRIBUTE);
02485   if( memory_IsUndef(vFile) )ERROR(COMMAND_ERROR_INVALID_FILE_NAME);
02486 
02487 
02488   SECUREFILE(vFile)
02489   CONVERT2ZCHAR(  vFile  , pszFile  );
02490   if( !stricmp(pszAttributeSymbol,"owner") ){
02491     vAttribute = CONVERT2STRING(vAttribute);
02492     CONVERT2ZCHAR(  vAttribute , pszAttribute );
02493     iErrorC = HOOK_CHOWN(pszFile,pszAttribute);
02494     FREE(pszAttribute);
02495     }
02496   else if( !stricmp(pszAttributeSymbol,"createtime") ){
02497     CONVERT2LONG(vAttribute);
02498     iErrorC = HOOK_SETCREATETIME(pszFile,LONGVALUE(vAttribute));
02499     }
02500   else if( !stricmp(pszAttributeSymbol,"modifytime") ){
02501     CONVERT2LONG(vAttribute);
02502     iErrorC = HOOK_SETMODIFYTIME(pszFile,LONGVALUE(vAttribute));
02503     }
02504   else if( !stricmp(pszAttributeSymbol,"accesstime") ){
02505     CONVERT2LONG(vAttribute);
02506     iErrorC = HOOK_SETACCESSTIME(pszFile,LONGVALUE(vAttribute));
02507     }
02508 
02509   else{
02510     FREE(pszFile);
02511     ERROR(COMMAND_ERROR_SETFILE_INVALID_ATTRIBUTE);
02512     }
02513   FREE(pszFile);
02514   if( iErrorC )ERROR(iErrorC);
02515 #endif
02516 END
02517 
02531 COMMAND(KILL)
02532 #if NOTIMP_KILL
02533 NOTIMPLEMENTED;
02534 #else
02535 
02536   long pid;
02537   NODE nItem;
02538 
02539   USE_CALLER_MORTALS;
02540 
02541   nItem = PARAMETERLIST;
02542   pid = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(CAR(nItem))));
02543   ASSERTOKE;
02544 
02545   RESULT = NEWMORTALLONG;
02546   ASSERTNULL(RESULT)
02547   if( HOOK_KILLPROC(pid) )
02548     LONGVALUE(RESULT) = 0L;
02549   else
02550     LONGVALUE(RESULT) = -1L;
02551 
02552 #endif
02553 END
02554 
02561 #define MAXOWNERLEN 512
02562 COMMAND(FOWNER)
02563 #if NOTIMP_FOWNER
02564 NOTIMPLEMENTED;
02565 #else
02566 
02567   char *pszOwnerBuffer,*pszFileName;
02568 
02569   long cbOwnerBuffer;
02570   VARIABLE vFileName;
02571 
02572   USE_CALLER_MORTALS;
02573 
02574   vFileName = CONVERT2STRING(_EVALUATEEXPRESSION(CAR(PARAMETERLIST)));
02575   ASSERTOKE;
02576   SECUREFILE(vFileName)
02577   CONVERT2ZCHAR(vFileName,pszFileName);
02578   pszOwnerBuffer = ALLOC( MAXOWNERLEN );
02579   if( pszOwnerBuffer == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
02580   cbOwnerBuffer = MAXOWNERLEN;
02581   if( HOOK_GETOWNER(pszFileName,pszOwnerBuffer,cbOwnerBuffer) ){
02582     RESULT = NULL;
02583     RETURN;
02584     }
02585   FREE(pszFileName);
02586   RESULT = NEWMORTALSTRING(cbOwnerBuffer=strlen(pszOwnerBuffer));
02587   ASSERTNULL(RESULT)
02588   memcpy(STRINGVALUE(RESULT),pszOwnerBuffer,cbOwnerBuffer);
02589 
02590 #endif
02591 END
02592 
02603 COMMAND(FCRYPT)
02604 #if NOTIMP_FCRYPT
02605 NOTIMPLEMENTED;
02606 #else
02607 
02608   char *pszString,*pszSalt;
02609   char szResult[13];
02610   VARIABLE vString,vSalt;
02611   NODE nItem;
02612 
02613   USE_CALLER_MORTALS;
02614 
02615   nItem = PARAMETERLIST;
02616 
02617   vString = CONVERT2STRING(_EVALUATEEXPRESSION(CAR(nItem)));
02618   ASSERTOKE;
02619   nItem = CDR(nItem);
02620   vSalt = CONVERT2STRING(_EVALUATEEXPRESSION(CAR(nItem)));
02621   ASSERTOKE;
02622 
02623   if( memory_IsUndef(vString) || memory_IsUndef(vSalt) ){
02624     RESULT = NULL;
02625     RETURN;
02626     }
02627 
02628   CONVERT2ZCHAR(vString,pszString);
02629   CONVERT2ZCHAR(vSalt,pszSalt);
02630 
02631   HOOK_FCRYPT(pszString,pszSalt,szResult);
02632 
02633   FREE(pszString);
02634   FREE(pszSalt);
02635 
02636   RESULT = NEWMORTALSTRING(12);
02637   ASSERTNULL(RESULT)
02638   memcpy(STRINGVALUE(RESULT),szResult,12);
02639 
02640 #endif
02641 END
02642 
02652 COMMAND(FORK)
02653 #if NOTIMP_FORK
02654 NOTIMPLEMENTED;
02655 #else
02656 NOTIMPLEMENTED;
02657 #endif
02658 END
02659 
02678 COMMAND(CREATEPROCESS)
02679 #if NOTIMP_CREATEPROCESS
02680 NOTIMPLEMENTED;
02681 #else
02682 
02683   char *pszCommandLine;
02684   VARIABLE vCommandLine;
02685   long lPid;
02686 
02687   USE_CALLER_MORTALS;
02688 
02689   vCommandLine = CONVERT2STRING(_EVALUATEEXPRESSION(CAR(PARAMETERLIST)));
02690   ASSERTOKE;
02691   if( memory_IsUndef(vCommandLine) ){
02692     RESULT = NULL;
02693     RETURN;
02694     }
02695 
02696   SECUREFILE(vCommandLine)
02697   CONVERT2ZCHAR(vCommandLine,pszCommandLine);
02698 
02699   lPid = HOOK_CREATEPROCESS(pszCommandLine);
02700 
02701   FREE(pszCommandLine);
02702 
02703   RESULT = NEWMORTALLONG;
02704   ASSERTNULL(RESULT)
02705   LONGVALUE(RESULT) = lPid;
02706 
02707 #endif
02708 END
02709 
02749 COMMAND(CREATEPROCESSEX)
02750 #if NOTIMP_CREATEPROCESSEX
02751 NOTIMPLEMENTED;
02752 #else
02753 
02754   char *pszCommandLine;
02755   VARIABLE vCommandLine,vTimeOut;
02756   unsigned long lPid,lExitCode;
02757   NODE nItem;
02758   LEFTVALUE LetThisVariable;
02759   long refcount;
02760   int iError;
02761 
02762   nItem = PARAMETERLIST;
02763 
02764   USE_CALLER_MORTALS;
02765 
02766   vCommandLine = CONVERT2STRING(_EVALUATEEXPRESSION(CAR(nItem)));
02767   ASSERTOKE;
02768   if( memory_IsUndef(vCommandLine) ){
02769     RESULT = NULL;
02770     RETURN;
02771     }
02772 
02773   /* check that the command string does not contain zero character */
02774   SECUREFILE(vCommandLine)
02775   CONVERT2ZCHAR(vCommandLine,pszCommandLine);
02776 
02777   nItem = CDR(nItem);
02778   vTimeOut = CONVERT2LONG(_EVALUATEEXPRESSION(CAR(nItem)));
02779   ASSERTOKE;
02780 
02781   nItem = CDR(nItem);
02782   LetThisVariable = EVALUATELEFTVALUE(CAR(nItem));
02783   ASSERTOKE;
02784   DEREFERENCE(LetThisVariable);
02785 
02786   iError = HOOK_CREATEPROCESSEX(pszCommandLine,LONGVALUE(vTimeOut),&lPid,&lExitCode);
02787 
02788   FREE(pszCommandLine);
02789   if( iError == FILESYSE_TIMEOUT ){
02790     /* if this variable had value assigned to it then release that value */
02791     if( *LetThisVariable )memory_ReleaseVariable(pEo->pMo,*LetThisVariable);
02792     *LetThisVariable = NEWLONG;
02793     if( *LetThisVariable == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
02794     LONGVALUE(*LetThisVariable) = lPid;
02795     ERROR(COMMAND_ERROR_TIMEOUT);
02796     }
02797 
02798   if( iError == FILESYSE_SUCCESS ){
02799     RESULT = NEWMORTALLONG;
02800     ASSERTNULL(RESULT)
02801     LONGVALUE(RESULT) = lExitCode;
02802     }
02803   ERROR(iError);
02804 #endif
02805 END
02806 
02818 COMMAND(WAITPID)
02819 #if NOTIMP_WAITPID
02820 NOTIMPLEMENTED;
02821 #else
02822 
02823   VARIABLE vPid;
02824   NODE nItem;
02825   LEFTVALUE LetThisVariable;
02826   long refcount;
02827   long Result;
02828   long lExitCode;
02829 
02830   nItem = PARAMETERLIST;
02831 
02832   USE_CALLER_MORTALS;
02833 
02834   vPid = CONVERT2LONG(_EVALUATEEXPRESSION(CAR(PARAMETERLIST)));
02835   ASSERTOKE;
02836   if( memory_IsUndef(vPid) ){
02837     RESULT = NULL;
02838     RETURN;
02839     }
02840 
02841   nItem = CDR(nItem);
02842   LetThisVariable = EVALUATELEFTVALUE(CAR(nItem));
02843   ASSERTOKE;
02844   DEREFERENCE(LetThisVariable);
02845 
02846   Result = HOOK_WAITPID(LONGVALUE(vPid),&lExitCode);
02847 
02848   /* if this variable had value assigned to it then release that value */
02849   if( *LetThisVariable )memory_ReleaseVariable(pEo->pMo,*LetThisVariable);
02850   *LetThisVariable = NEWLONG;
02851   if( *LetThisVariable == NULL )ERROR(COMMAND_ERROR_MEMORY_LOW);
02852   if( Result == 0) lExitCode = 0;
02853   LONGVALUE(*LetThisVariable) = lExitCode;
02854 
02855   RESULT = NEWMORTALLONG;
02856   ASSERTNULL(RESULT)
02857   LONGVALUE(RESULT) = Result;
02858 
02859 #endif
02860 END
02861 
02872 COMMAND(BINMF)
02873 #if NOTIMP_BINMF
02874 NOTIMPLEMENTED;
02875 #else
02876 
02877   long FileNumber;
02878   pFileCommandObject pFCO;
02879 
02880   INITIALIZE;
02881   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
02882   FileNumber = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
02883   ASSERTOKE;
02884 
02885   if( FileNumber < 1 || FileNumber > MAXFILES )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
02886   FileNumber --;
02887   if( ! pFCO->mode[FileNumber] )ERROR(COMMAND_ERROR_FILE_IS_NOT_OPENED);
02888   if( pFCO->mode[FileNumber] != 's' )/* sockets are binary and binary only */
02889     HOOK_BINMODE(THISFILEP);
02890 #endif
02891 END
02892 
02902 COMMAND(TXTMF)
02903 #if NOTIMP_TEXTMF
02904 NOTIMPLEMENTED;
02905 #else
02906 
02907   long FileNumber;
02908   pFileCommandObject pFCO;
02909 
02910   INITIALIZE;
02911   pFCO = (pFileCommandObject)PARAMPTR(CMD_OPEN);
02912 
02913   FileNumber = LONGVALUE(CONVERT2LONG(EVALUATEEXPRESSION(PARAMETERNODE)));
02914   ASSERTOKE;
02915 
02916   if( FileNumber < 1 || FileNumber > MAXFILES )ERROR(COMMAND_ERROR_BAD_FILE_NUMBER);
02917   FileNumber --;
02918   if( ! pFCO->mode[FileNumber] )ERROR(COMMAND_ERROR_FILE_IS_NOT_OPENED);
02919   if( pFCO->mode[FileNumber] != 's' )/* sockets are binary and binary only */
02920     HOOK_TEXTMODE(THISFILEP);
02921 #endif
02922 END
02923 
02924 COMMAND(BINMO)
02925 #if NOTIMP_BINMO
02926 NOTIMPLEMENTED;
02927 #else
02928   HOOK_BINMODE(stdout);
02929 #endif
02930 END
02931 
02932 COMMAND(BINMI)
02933 #if NOTIMP_BINMI
02934 NOTIMPLEMENTED;
02935 #else
02936   HOOK_BINMODE(stdin);
02937 #endif
02938 END
02939 
02940 COMMAND(TXTMO)
02941 #if NOTIMP_TEXTMO
02942 NOTIMPLEMENTED;
02943 #else
02944   HOOK_TEXTMODE(stdout);
02945 #endif
02946 END
02947 
02948 COMMAND(TXTMI)
02949 #if NOTIMP_TEXTMI
02950 NOTIMPLEMENTED;
02951 #else
02952   HOOK_TEXTMODE(stdin);
02953 #endif
02954 END

Generated on Sun Mar 12 23:56:26 2006 for ScriptBasic by  doxygen 1.4.6-NO