FT_Stream_Open( FT_Stream stream, const char* filepathname ) { // FILE* file; BPTR file; // TetiSoft struct FileInfoBlock* fib; // TetiSoft if ( !stream ) return FT_Err_Invalid_Stream_Handle; // file = fopen( filepathname, "rb" ); file = Open( filepathname, MODE_OLDFILE ); // TetiSoft if ( !file ) { FT_ERROR(( "FT_Stream_Open:" )); FT_ERROR(( " could not open `%s'\n", filepathname )); return FT_Err_Cannot_Open_Resource; } // fseek( file, 0, SEEK_END ); // astream->size = ftell( file ); // fseek( file, 0, SEEK_SET ); fib = AllocDosObject( DOS_FIB, NULL ); if ( !fib ) { Close ( file ); FT_ERROR(( "FT_Stream_Open:" )); FT_ERROR(( " could not open `%s'\n", filepathname )); return FT_Err_Cannot_Open_Resource; } if ( !( ExamineFH( file, fib ) ) ) { FreeDosObject( DOS_FIB, fib ); Close ( file ); FT_ERROR(( "FT_Stream_Open:" )); FT_ERROR(( " could not open `%s'\n", filepathname )); return FT_Err_Cannot_Open_Resource; } stream->size = fib->fib_Size; FreeDosObject( DOS_FIB, fib ); // stream->descriptor.pointer = file; stream->descriptor.pointer = (void *)file; stream->pathname.pointer = (char*)filepathname; stream->pos = 0; stream->read = ft_io_stream; stream->close = ft_close_stream; FT_TRACE1(( "FT_Stream_Open:" )); FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", filepathname, stream->size )); return FT_Err_Ok; }
static PtrT ReadFileToCustomMemory(const StrT fileName, uint32_t memFlags) { BPTR fh; PtrT data = NULL; PtrT path = AbsPath(fileName); if ((fh = Open(path, MODE_OLDFILE))) { struct FileInfoBlock *infoBlock; if ((infoBlock = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, NULL))) { if (ExamineFH(fh, infoBlock)) { size_t dataLen = infoBlock->fib_Size; if ((data = MemNewCustom(dataLen, memFlags, NULL))) { if (dataLen != Read(fh, data, dataLen)) { MemUnref(data); data = NULL; } } } FreeDosObject(DOS_FIB, infoBlock); } Close(fh); } MemUnref(path); return data; }
long Q_filesize (const char *path) { long size = -1; BPTR fh = Open((const STRPTR) path, MODE_OLDFILE); if (fh) { struct FileInfoBlock *fib = (struct FileInfoBlock*) AllocDosObject(DOS_FIB, NULL); if (fib != NULL) { if (ExamineFH(fh, fib)) size = fib->fib_Size; FreeDosObject(DOS_FIB, fib); } Close(fh); } return size; }
/************************************************************************** Returns the size of a file **************************************************************************/ LONG GetFileSize( BPTR fileh ) { struct FileInfoBlock *fib = (struct FileInfoBlock*)AllocDosObject( DOS_FIB, NULL ); LONG size = -1; if (fib) { if (ExamineFH( fileh, fib )) { if ((fib->fib_DirEntryType > 0) && (fib->fib_DirEntryType != ST_SOFTLINK)) { size = 0; } size = fib->fib_Size; } FreeDosObject( DOS_FIB, fib ); } return size; }
int Q_FileType (const char *path) { int type = FS_ENT_NONE; BPTR fh = Open((const STRPTR) path, MODE_OLDFILE); if (fh) { struct FileInfoBlock *fib = (struct FileInfoBlock*) AllocDosObject(DOS_FIB, NULL); if (fib != NULL) { if (ExamineFH(fh, fib)) { if (fib->fib_DirEntryType >= 0) type = FS_ENT_DIRECTORY; else type = FS_ENT_FILE; } FreeDosObject(DOS_FIB, fib); } Close(fh); } return type; }
FT_Stream_Open( FT_Stream stream, const char* filepathname ) { struct FileInfoBlock* fib; struct SysFile* sysfile; if ( !stream ) return FT_THROW( Invalid_Stream_Handle ); #ifdef __amigaos4__ sysfile = AllocMem ( sizeof (struct SysFile ), MEMF_SHARED ); #else sysfile = AllocMem ( sizeof (struct SysFile ), MEMF_PUBLIC ); #endif if ( !sysfile ) { FT_ERROR(( "FT_Stream_Open:" )); FT_ERROR(( " could not open `%s'\n", filepathname )); return FT_THROW( Cannot_Open_Resource ); } sysfile->file = Open( (STRPTR)filepathname, MODE_OLDFILE ); if ( !sysfile->file ) { FreeMem ( sysfile, sizeof ( struct SysFile )); FT_ERROR(( "FT_Stream_Open:" )); FT_ERROR(( " could not open `%s'\n", filepathname )); return FT_THROW( Cannot_Open_Resource ); } fib = AllocDosObject( DOS_FIB, NULL ); if ( !fib ) { Close ( sysfile->file ); FreeMem ( sysfile, sizeof ( struct SysFile )); FT_ERROR(( "FT_Stream_Open:" )); FT_ERROR(( " could not open `%s'\n", filepathname )); return FT_THROW( Cannot_Open_Resource ); } if ( !( ExamineFH( sysfile->file, fib ) ) ) { FreeDosObject( DOS_FIB, fib ); Close ( sysfile->file ); FreeMem ( sysfile, sizeof ( struct SysFile )); FT_ERROR(( "FT_Stream_Open:" )); FT_ERROR(( " could not open `%s'\n", filepathname )); return FT_THROW( Cannot_Open_Resource ); } stream->size = fib->fib_Size; FreeDosObject( DOS_FIB, fib ); stream->descriptor.pointer = (void *)sysfile; stream->pathname.pointer = (char*)filepathname; sysfile->iobuf_start = 0; sysfile->iobuf_end = 0; stream->pos = 0; stream->read = ft_amiga_stream_io; stream->close = ft_amiga_stream_close; if ( !stream->size ) { ft_amiga_stream_close( stream ); FT_ERROR(( "FT_Stream_Open:" )); FT_ERROR(( " opened `%s' but zero-sized\n", filepathname )); return FT_THROW( Cannot_Open_Stream ); } FT_TRACE1(( "FT_Stream_Open:" )); FT_TRACE1(( " opened `%s' (%ld bytes) successfully\n", filepathname, stream->size )); return FT_Err_Ok; }
// Examine a file long LIBFUNC L_ExamineBuf( REG(a0, APTR file), REG(a1, struct FileInfoBlock *fib)) { return ExamineFH(((BufFile *)file)->file,fib); }
BOOL __asm __saveds L_GetFileVersion( register __a0 char *name, register __d0 short *version, register __d1 short *revision, register __a1 struct DateStamp *date, register __a2 APTR progress) { char *buffer; BPTR file; short size,pos; char match_string[6]; short match=0; BOOL ok=0; struct TagItem tags[2]; unsigned short word_read=0,wordpos=0; unsigned short verflags=0; unsigned long wordcount=0,headerstart=0,matchpos=0,headerlength=0,limit; // Initialise things *version=0; *revision=0; if (date) date->ds_Days=0; // Allocate buffer if (!(buffer=AllocVec(4096,0))) return 0; // Open file if (!(file=Open(name,MODE_OLDFILE))) { FreeVec(buffer); return 0; } // Initialise tags tags[0].ti_Tag=PW_FileSize; tags[1].ti_Tag=TAG_END; // Got progress? if (progress) { struct FileInfoBlock __aligned info; // Get file info if (ExamineFH(file,&info)) { // Set file size tags[0].ti_Data=info.fib_Size; } else tags[0].ti_Data=0; // Set bar L_SetProgressWindow(progress,tags); // No file size? if (!tags[0].ti_Data) progress=0; } // Set tag to update size tags[0].ti_Tag=PW_FileDone; tags[0].ti_Data=0; // Build match string match_string[0]='$'; match_string[1]='V'; match_string[2]='E'; match_string[3]='R'; match_string[4]=':'; // Wordcount limit limit=256; // Read first 4k while ((size=Read(file,buffer,4096))>-1) { short extra=0; // End of file? if (size==0) { // Did we find matchword? if (verflags&VERF_MATCH) { // Seek to match position Seek(file,matchpos,OFFSET_BEGINNING); // Read into buffer size=Read(file,buffer,512); // Signal a match match=5; verflags&=~VERF_MATCH; } // Failed to find anything else break; } // Got progress? if (progress) { // Check for abort if (L_CheckProgressAbort(progress)) break; // Increment total, update display tags[0].ti_Data+=size; L_SetProgressWindow(progress,tags); } // Leave last 32 bytes if (size>4064) { extra=size-4064; size=4064; } // Go through buffer for (pos=0;pos<size && match<5;pos++) { // Add to word if (wordpos==0) { // High byte word_read=((unsigned char)buffer[pos])<<8; wordpos=1; } // Low byte else if (!(verflags&VERF_FAIL)) { // This completes the word word_read|=(unsigned char)buffer[pos]; wordpos=0; // Increment count ++wordcount; // Executable? if (word_read==VER_EXECUTABLE && wordcount==2) { verflags|=VERF_GOT_EXE; } // Correct header? else if (verflags&VERF_GOT_EXE && (word_read==VER_HEADER_CODE || word_read==VER_HEADER_DATA) && !headerstart) { // Set flag verflags|=VERF_GOT_HEADER; headerstart=((wordcount-1)<<1)+6; // Get length of the header CopyMem((char *)(buffer+pos+1),(char *)&headerlength,sizeof(headerlength)); // Convert length to words ++headerlength; headerlength<<=1; } // Match word? else if (verflags&VERF_GOT_EXE && verflags&VERF_GOT_HEADER && word_read==VER_MATCHWORD) { struct Resident res; // Get resident structure CopyMem((char *)(buffer+pos-1),(char *)&res,sizeof(struct Resident)); // Get position of ID string from hunk offset matchpos=((long)res.rt_IdString)+headerstart-1; // Set match flag verflags|=VERF_MATCH|VERF_FAIL; } // Got a header? else if (headerstart) { // Decrement a word from the headerlength if ((--headerlength)<=0) { // End of the header verflags&=~VERF_GOT_HEADER; headerstart=0; // New word count limit limit=wordcount+256; } } // Have we gone too far? if (wordcount>limit && !(verflags&VERF_GOT_HEADER)) verflags|=VERF_FAIL; } // Check for match if (buffer[pos]==match_string[match]) { // Increment match count ++match; } // Reset match count else match=0; } // Got a match? if (match==5) { short day,month,year; char datebuf[20]; struct DateTime dt; // Got progress? if (progress) { // Show full bar tags[0].ti_Data=(ULONG)-1; L_SetProgressWindow(progress,tags); } // Bump position ++pos; // On a space? if (buffer[pos]==' ') { // Find first non-space while (pos<size && buffer[pos]==' ') ++pos; if (pos>=size) break; } // Find first space while (pos<size && buffer[pos]!=' ' && buffer[pos]!='\n') ++pos; if (pos>=size || buffer[pos]=='\n') break; // Find first number while (pos<size && (buffer[pos]<'0' || buffer[pos]>'9')) ++pos; if (pos>=size) break; // Get version number *version=atoi(buffer+pos); // Find decimal point while (pos<size && buffer[pos]!='.' && buffer[pos]!=' ') ++pos; if (pos>=size-1) break; // Check next number ++pos; if (buffer[pos]>='0' && buffer[pos]<='9') *revision=atoi(buffer+pos); // We're ok at this point ok=1; // Want date? if (!date) break; // Find parentheses for date while (pos<size && buffer[pos]!='(') ++pos; if (pos>=size) break; // Get day ++pos; day=atoi(buffer+pos); if (day<1 || day>31) break; // Skip a segment if ((pos=version_skip(buffer,pos,size))==-1) break; // Get month month=atoi(buffer+pos); if (month<1 || month>12) { char buf[4]; // Maybe this is a character month buf[0]=buffer[pos]; buf[1]=buffer[pos+1]; buf[2]=buffer[pos+2]; buf[3]=0; // See if it matches for (month=0;month<12;month++) if (stricmp(month_str[month],buf)==0) break; // Did it match? if (month<12) ++month; else break; } // Skip a segment if ((pos=version_skip(buffer,pos,size))==-1) break; // Get year year=atoi(buffer+pos); // Check year if (year>1900 && year<2000) year-=1900; if (year<78) break; while (year>100) year-=100; // Build string lsprintf(datebuf,"%ld-%ld-%ld",month,day,year); // Convert to datestamp dt.dat_Format=FORMAT_USA; dt.dat_Flags=0; dt.dat_StrDay=0; dt.dat_StrDate=datebuf; dt.dat_StrTime="00:00:00"; StrToDate(&dt); // Copy datestamp *date=dt.dat_Stamp; break; } // Any extra? if (extra>0) { // Seek back for extra Seek(file,-extra,OFFSET_CURRENT); } } // Close file, free buffer Close(file); FreeVec(buffer); return ok; }
int main(void) { struct DateTime curr; char day[LEN_DATSTRING]; char time[LEN_DATSTRING]; char date[LEN_DATSTRING]; struct DateStamp stamp; curr.dat_Format = FORMAT_DOS; curr.dat_Flags = 0; curr.dat_StrDay = day; curr.dat_StrDate = date; curr.dat_StrTime = time; DateStamp(&curr.dat_Stamp); DateToStr(&curr); Printf("Current time: %s, %s, %s\n", day, date, time); BPTR fh = Open("__TEST__", MODE_NEWFILE); if (fh != BNULL) { struct FileInfoBlock *fib = AllocDosObject(DOS_FIB, NULL); if (fib != NULL) { if (ExamineFH(fh, fib)) { curr.dat_Stamp = fib->fib_Date; DateToStr(&curr); Printf("File modification time: %s, %s, %s\n", day, date, time); } else PrintFault(IoErr(), "Examine failed"); Printf("Waiting 5 seconds\n"); Delay(5*50); DateStamp(&stamp); Printf("Calling SetFileDate\n"); if(SetFileDate("__TEST__", &stamp)) { if (ExamineFH(fh, fib)) { curr.dat_Stamp = fib->fib_Date; DateToStr(&curr); Printf("New file modification time: %s, %s, %s\n", day, date, time); } else PrintFault(IoErr(), "Examine failed"); } else PrintFault(IoErr(), "SetFileDate"); FreeDosObject(DOS_FIB, fib); } else PrintFault(IoErr(), "Couldn't alloc FileInfoBlock"); Close(fh); DeleteFile("__TEST__"); } else PrintFault(IoErr(), "Couldn't create file"); return 0; }
int __stat(BPTR lock, struct stat *sb, BOOL filehandle) { struct FileInfoBlock *fib; UBYTE *buffer; int buffersize = 256; int fallback_to_defaults = 0; BOOL Examined; fib = AllocDosObject(DOS_FIB, NULL); if (!fib) { errno = __stdc_ioerr2errno(IoErr()); return -1; } Examined = filehandle ? ExamineFH(lock, fib) : Examine(lock, fib); if (!Examined) { if(IoErr() == ERROR_NOT_IMPLEMENTED || IoErr() == ERROR_ACTION_NOT_KNOWN) { fallback_to_defaults = 1; } else { errno = __stdc_ioerr2errno(IoErr()); FreeDosObject(DOS_FIB, fib); return -1; } } /* Get the full path of the stated filesystem object and use it to compute hash value */ do { BOOL GotName; if(!(buffer = AllocVec(buffersize, MEMF_ANY))) { errno = ENOMEM; FreeDosObject(DOS_FIB, fib); return -1; } GotName = filehandle ? NameFromFH(lock, buffer, buffersize) : NameFromLock(lock, buffer, buffersize); if(GotName) break; else if( IoErr() == ERROR_OBJECT_IN_USE || IoErr() == ERROR_NOT_IMPLEMENTED || IoErr() == ERROR_ACTION_NOT_KNOWN || (IoErr() == ERROR_OBJECT_NOT_FOUND && fib->fib_EntryType == ST_PIPEFILE)) { /* We can't retrieve name because lock is an exclusive lock or Examine is not implemented in this handler or the lock refers to an XPIPE: file having always empty name */ buffer[0] = '\0'; break; } else if(IoErr() != ERROR_LINE_TOO_LONG) { errno = __stdc_ioerr2errno(IoErr()); FreeDosObject(DOS_FIB, fib); FreeVec(buffer); return -1; } FreeVec(buffer); buffersize *= 2; } while(TRUE); // We need a FileLock. Otherwise a call of Info() within __fill_statbuffer() will crash // FIXME: how can we get a lock on an exclusive file? if (filehandle) { BPTR filelock = DupLockFromFH(lock); __fill_statbuffer(sb, (char*) buffer, fib, fallback_to_defaults, filelock); UnLock(filelock); } else { __fill_statbuffer(sb, (char*) buffer, fib, fallback_to_defaults, lock); } FreeVec(buffer); FreeDosObject(DOS_FIB, fib); return 0; }