Fix IO memory access .. SB128 driver makes noises in VMWare - CMI is untested (Curren...
[AROS.git] / workbench / c / Info.c
blob3f9c47e2de1f25b8f2a48450a205fed0ff269ccb
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Info Cli Command
6 Lang: English
7 */
9 /******************************************************************************
12 NAME
14 Info
16 SYNOPSIS
18 DISKS/S, VOLS=VOLUMES/S, ALL/S, BLOCKS/S, DEVICES/M
20 LOCATION
24 FUNCTION
26 Show information on file system devices and volumes. When given no
27 arguments, information on all devices and volumes found in the system
28 is displayed. If information is wanted only for some specific devices,
29 these names may be given as arguments.
31 INPUTS
33 DISKS -- show information on file system devices
34 VOLS -- show information on volumes
35 ALL -- show information on bad devices or volumes
36 BLOCKS -- show additional block size and usage information
37 DEVICES -- device names to show information about
39 RESULT
41 NOTES
43 EXAMPLE
45 Info
47 Unit Size Used Free Full Errs State Type Name
48 Harddisk: 964.1M 776.7M 187.4M 81% 0 read/write OFS AROS
49 RAM: 8.0M 7.1M 7.1M 12% 0 read/write OFS Ram Disk
51 BUGS
53 SEE ALSO
55 INTERNALS
57 The original source showed that AROS version of ReadArgs() handles
58 the /M switch with zero arguments differently from AmigaOS. While AROS
59 returns an array where the first pointer is NULL, AmigaOS just returns
60 NULL.
62 HISTORY
64 16.11.2000 SDuvan -- converted to AROS
65 23.12.2000 SDuvan -- changed semantics and updated
66 (now fully functional)
67 17.02.2005 Joe Fenton -- fixed 64bit calculation
69 Based on the original by:
70 © 1997-1998 by Stephan Rupprecht
71 All rights resevered
72 ******************************************************************************/
74 #define DEBUG 0
75 #include <aros/debug.h>
77 #include <dos/dos.h>
78 #include <dos/dosextens.h>
79 #include <dos/filehandler.h>
80 #include <exec/memory.h>
81 #include <libraries/locale.h>
83 #include <proto/dos.h>
84 #include <proto/exec.h>
85 #include <proto/utility.h>
86 #include <proto/locale.h>
87 #include <proto/alib.h>
89 #include <string.h>
91 #define ID_MAC_DISK2 (0x4d414300L) /* MAC\0 - xfs mac disk */
92 #define ID_MNX1_DISK (0x4d4e5801L) /* MNX\1 - xfs minix disk */
93 #define ID_MNX2_DISK (0x4d4e5802L) /* MNX\2 - xfs minix disk */
94 #define ID_QL5A_DISK (0x514c3541L) /* QL5A - xfs ql 720k / ed disk */
95 #define ID_QL5B_DISK (0x514c3542L) /* QL5B - xfs ql 1440k disk */
96 #define ID_ZXS0_DISK (0x5a585300L) /* Spectrum Disciple - xfs */
97 #define ID_ZXS1_DISK (0x5a585301L) /* Spectrum UniDos - xfs */
98 #define ID_ZXS2_DISK (0x5a585302L) /* Spectrum SamDos - xfs */
99 #define ID_ZXS4_DISK (0x5a585304L) /* Spectrum Opus 180k - xfs */
100 #define ID_ARME_DISK (0x41524d44L) /* Archimedes - xfs */
101 #define ID_ARMD_DISK (0x41524d43L) /* Archimedes - xfs */
102 #define ID_CPM_DISK (0x43505c4dL) /* CP/M - xfs */
103 #define ID_ZXS3_DISK (0x5a585303L) /* ZXS\3 - Plus3Dos xfs */
104 #define ID_1541_DISK (0x31353431L) /* 1541 - xfs */
105 #define ID_1581_DISK (0x31353831L) /* 1581 - xfs */
106 #define ID_MAC_DISK (0x4d534800L) /* MSH\0 - CrossDos MACDisk ?! */
107 #define ID_ACD0_DISK (0x41434400L) /* ACD\0 - AmiCDFS disk */
108 #define ID_CDFS_DISK (0x43444653L) /* CDFS - AmiCDFS disk */
109 #define ID_CACHECDFS_DISK (0x43443031L)
110 #define ID_ASIMCDFS_DISK (0x662dabacL)
111 #define ID_PFS2_DISK (0x50465302L)
112 #define ID_PFS2_SCSI_DISK (0x50445300L)
113 #define ID_PFS2_muFS_DISK (0x6d755046L)
114 #define ID_FLOPPY_PFS_DISK (0x50465300L)
115 #define ID_P2A0_DISK (0x50324130L)
116 #define ID_AFS0_DISK (0x41465300L) /* AFS\0 */
117 #define ID_muFS_DISK (0x6d754653L) /* muFS - Mulituserfsys */
118 #define ID_FAT12_DISK (0x46415400L) /* FAT12 */
119 #define ID_FAT16_DISK (0x46415401L) /* FAT16 */
120 #define ID_FAT32_DISK (0x46415402L) /* FAT32 */
123 /* Prototypes */
125 ULONG ComputeKBytes(ULONG a, ULONG b);
126 void FmtProcedure(struct Hook *hook, char a, struct Locale *locale);
127 ULONG ExtUDivMod32(ULONG a, ULONG b, ULONG *mod);
128 void doInfo();
131 const TEXT VersionStr[] = "$VER: Info 41.1 (16.11.2000)";
133 struct Catalog *cat;
134 struct Locale *loc = NULL;
135 ULONG MaxLen;
137 APTR Pool;
140 /* catalog string id:s */
141 enum
143 UNIT,
144 DEVTITLE,
145 DISKSTITLE,
146 DEVFMTSTR,
147 DATEFMTSTR,
148 READONLY,
149 READWRITE,
150 VALIDATING,
151 MOUNTEDSTR,
152 SMALLNUMFMT,
153 BIGNUMFMT,
154 VOLNAMEFMTSTR,
155 BLOCKSSTR
159 struct InfoDosNode
161 struct InfoDosNode *Next;
162 ULONG IsVolume;
163 ULONG DosType;
164 struct MsgPort *Task;
165 struct DateStamp VolumeDate;
166 TEXT Name[108];
169 struct InfoDosNode *head = NULL;
172 struct DiskTypeList
173 { ULONG id;
174 STRPTR str;
177 struct DiskTypeList dtl[] =
179 { ID_DOS_DISK, "OFS" },
180 { ID_FFS_DISK, "FFS" },
181 { ID_INTER_DOS_DISK, "OFS-INT" },
182 { ID_INTER_FFS_DISK, "FFS-INT" },
183 { ID_FASTDIR_DOS_DISK, "OFS-DC" },
184 { ID_FASTDIR_FFS_DISK, "FFS-DC" },
185 { ID_MSDOS_DISK, "MS-DOS" },
186 { ID_ACD0_DISK, "CDFS" },
187 { ID_CACHECDFS_DISK, "CDFS" },
188 { ID_ASIMCDFS_DISK, "CDFS" },
189 { ID_NOT_REALLY_DOS, "NO DOS" },
190 { ID_MAC_DISK2, "MAC" },
191 { ID_MNX1_DISK, "Minix" },
192 { ID_QL5A_DISK, "QL720k" },
193 { ID_QL5B_DISK, "QL1.4M" },
194 { ID_CPM_DISK, "CP/M" },
195 { ID_ZXS3_DISK, "+3Dos" },
196 { ID_ZXS0_DISK, "Disciple " },
197 { ID_ZXS1_DISK, "UniDos" },
198 { ID_ZXS2_DISK, "SamDos" },
199 { ID_ZXS4_DISK, "Opus" },
200 { ID_P2A0_DISK, "NETWORK" },
201 { ID_FAT12_DISK, "FAT12" },
202 { ID_FAT16_DISK, "FAT16" },
203 { ID_FAT32_DISK, "FAT32" },
204 { ID_FAT32_DISK, "FAT32" },
205 { ID_SFS_BE_DISK, "SFS" },
206 { ID_SFS_LE_DISK, "sfs" },
207 { 0L, 0L }
211 /****************************************************************************/
213 int UtilityBase_version = 0;
214 int LocaleBase_version = 0;
216 int __nocommandline;
218 int main(void)
220 static struct TagItem loctags[] = { { OC_Version, 1 },
221 { TAG_END , 0 } };
222 cat = OpenCatalogA(NULL, "info_com.catalog", loctags);
223 loc = OpenLocale(NULL);
225 D(bug("Calling doInfo()\n"));
227 doInfo();
229 CloseLocale(loc);
230 CloseCatalog(cat);
232 return RETURN_OK; /* TODO: Fix this */
236 CONST_STRPTR GetStrFromCat(ULONG id, CONST_STRPTR def)
238 if(cat != NULL)
240 def = GetCatalogStr(cat, id, def);
243 return def;
247 void VLPrintf(ULONG id, CONST_STRPTR def, const IPTR* argarray)
249 def = GetStrFromCat(id, def);
250 VPrintf(def, (IPTR *)argarray);
254 BOOL myMatchPatternNoCase(STRPTR *array, STRPTR str)
256 if(*array != NULL)
258 while(*array != NULL)
260 UBYTE matchstr[128];
261 UBYTE name[32];
262 UBYTE *p = *array++;
263 UBYTE len = strlen(p);
265 if(p[len - 1] != ':')
267 CopyMem(p, name, len);
268 name[len] = ':';
269 name[len + 1] = 0;
270 p = name;
273 if(ParsePatternNoCase(p, matchstr, sizeof(matchstr)) != -1)
275 if(MatchPatternNoCase(matchstr, str))
277 return TRUE;
282 return FALSE;
285 return TRUE;
289 BOOL ScanDosList(STRPTR *filter)
291 struct InfoDosNode *idn = 0L;
292 struct DosList *ndl, *dl;
293 STRPTR *strray = NULL, dummy = NULL;
294 BOOL err = FALSE;
296 D(bug("Entered ScanDosList()\n"));
298 if (filter == NULL) filter = &dummy;
300 if(*filter != NULL)
302 strray = AllocPooled(Pool, sizeof(STRPTR)*MAX_MULTIARGS);
304 if(strray != NULL)
306 STRPTR *p = filter;
307 LONG i = 0;
309 while(*p)
310 strray[i++] = *p++;
312 while(i < MAX_MULTIARGS)
313 strray[i++] = NULL;
315 else
316 return FALSE;
319 /* lock list of devices & vols */
320 dl = ndl = LockDosList(LDF_ASSIGNS | LDF_VOLUMES | LDF_DEVICES | LDF_READ);
322 if(strray != NULL)
324 STRPTR *p = strray;
326 while(*p)
327 p++;
329 while((ndl = NextDosEntry(ndl, LDF_ASSIGNS | LDF_VOLUMES | LDF_READ)) != NULL)
331 TEXT name[108];
332 STRPTR taskName = NULL; /* Initialized to avoid a warning */
334 __sprintf(name, "%b:", ndl->dol_Name);
336 if ((ndl->dol_Type > DLT_VOLUME) || !(myMatchPatternNoCase(strray, name)))
338 continue;
341 switch (ndl->dol_Type)
343 case DLT_VOLUME:
344 taskName = ((struct Task *)ndl->dol_Task->mp_SigTask)->tc_Node.ln_Name;
346 D(bug("Found volume %s\n", taskName));
347 break;
349 case DLT_DIRECTORY:
351 struct AssignList *al = ndl->dol_misc.dol_assign.dol_List;
353 taskName = ((struct Task *)((struct FileLock *)BADDR(ndl->dol_Lock))->fl_Task->mp_SigTask)->tc_Node.ln_Name;
355 D(bug("Found directory %s\n", taskName));
357 while(al != NULL)
359 *p++ = ""; // TODO!!! ((struct Task *)((struct FileLock *)BADDR(al->al_Lock))->fl_Task->mp_SigTask)->tc_Node.ln_Name;
360 al = al->al_Next;
363 break;
366 *p++ = taskName;
369 else
370 strray = filter;
372 ndl = dl;
374 while((ndl = NextDosEntry(ndl, LDF_VOLUMES | LDF_DEVICES | LDF_READ)) != NULL)
376 UBYTE len = 0;
377 UBYTE type = ndl->dol_Type;
378 UBYTE name[108];
380 /* do not start non-started handlers or open CON: or RAW: windows.. */
381 if(type == DLT_DEVICE && !ndl->dol_Task)
382 continue;
384 __sprintf(name, "%b:", ndl->dol_Name);
385 D(bug("Found name %s\n", name));
387 if((type == DLT_DEVICE) && (myMatchPatternNoCase(strray, name) == FALSE))
389 int i;
391 D(bug("Failure! -- name = %s, strray = %p\n", name, (void *)strray));
393 for (i = 0; strray[i] != NULL; i++)
395 D(bug("Strray %i = %s\n", i, strray[i]));
398 continue;
401 idn = (struct InfoDosNode *)AllocPooled(Pool, sizeof(struct InfoDosNode));
403 if(idn == NULL)
405 err = TRUE;
406 break;
409 idn->Task = ndl->dol_Task;
410 idn->IsVolume = type == DLT_VOLUME;
412 while((idn->Name[len] = name[len]))
413 len++;
415 if(type == DLT_VOLUME)
417 idn->VolumeDate = ((struct DeviceList *)ndl)->dl_VolumeDate;
418 idn->Name[len - 1] = '\0'; /* remove ':' */
420 else
422 BPTR ptr = ndl->dol_misc.dol_handler.dol_Startup;
423 struct FileSysStartupMsg *fssm = (struct FileSysStartupMsg *)BADDR(ptr);
425 idn->DosType = ID_DOS_DISK;
427 // DLT_DEVICE
428 if (len > MaxLen)
429 MaxLen = len;
431 if (fssm)
433 struct DosEnvec *de;
434 de = (struct DosEnvec *)BADDR(fssm->fssm_Environ);
436 if (de && (de->de_TableSize & 0xffffff00) == 0)
437 if (de->de_DosType)
438 idn->DosType = de->de_DosType;
442 /* kinda insert sort */
444 struct InfoDosNode *work = head;
445 struct InfoDosNode *prev = NULL;
447 while((work != NULL) && (Stricmp(idn->Name, work->Name) > 0))
449 prev = work;
450 work = work->Next;
453 if(prev != NULL)
454 prev->Next = idn;
455 else
456 head = idn;
458 idn->Next = work;
462 /* unlock list of devices and volumes */
463 UnLockDosList(LDF_ASSIGNS | LDF_VOLUMES | LDF_DEVICES | LDF_READ);
465 // strray freed at DeletePool
467 return !err;
471 void PrintNum(ULONG num)
473 /* MBytes ? */
474 if(num > 1023)
476 ULONG x, xx;
477 char fmt = 'M';
479 /* GBytes ? */
480 if(num > 0xfffff)
482 num >>= 10;
483 fmt = 'G';
486 num = ExtUDivMod32(UMult32(num, 100) >> 10, 100, &x);
488 /* round */
489 x = ExtUDivMod32(x, 10, &xx);
491 if(xx > 4)
493 if(++x > 9)
495 x = 0;
496 num++;
500 IPTR args[] = {num, x, fmt};
501 VLPrintf(BIGNUMFMT, "%5ld.%ld%lc", args);
503 else
505 IPTR args[] = { num };
506 VLPrintf(SMALLNUMFMT, "%7ldK", args);
511 STRPTR GetFSysStr(ULONG DiskType)
513 struct DiskTypeList *dtlptr = dtl;
515 STRPTR ptr = NULL;
517 do {
518 if(dtlptr->id == DiskType)
520 ptr = dtlptr->str;
521 break;
523 } while(*((ULONG *)dtlptr++));
525 if(ptr == NULL)
527 static TEXT buffer[5];
529 ptr = (STRPTR)buffer;
530 *((ULONG *)ptr) = AROS_LONG2BE(DiskType);
532 if(ptr[3] < ' ')
533 ptr[3] += '0';
535 ptr[4] = '\0';
538 return ptr;
542 enum
544 ARG_DISKS,
545 ARG_VOLS,
546 ARG_ALL,
547 ARG_BLOCKS,
548 ARG_DEVS,
549 NOOFARGS
553 void doInfo()
555 struct RDArgs *rdargs;
556 struct Process *proc;
557 struct Window *win;
558 struct InfoDosNode *idn;
560 struct InfoData *id = AllocVec(sizeof(struct InfoData), MEMF_ANY);
562 IPTR args[] = { (IPTR)FALSE,
563 (IPTR)FALSE,
564 (IPTR)FALSE,
565 (IPTR)FALSE,
566 (IPTR)NULL };
568 CONST_STRPTR unit = GetStrFromCat(UNIT, "Unit");
570 if(id == NULL)
572 PrintFault(ERROR_NO_FREE_STORE, NULL);
573 return;
576 Pool = CreatePool(MEMF_ANY, 1024, 1024);
578 if(Pool == NULL)
580 PrintFault(ERROR_NO_FREE_STORE, NULL);
581 return; /* ??? */
584 D(bug("Calling ReadArgs()\n"));
586 /* read arguments */
587 rdargs = ReadArgs("DISKS/S,VOLS=VOLUMES/S,ALL/S,BLOCKS/S,DEVICES/M",
588 args, NULL);
590 if(rdargs != NULL)
592 BOOL disks = (BOOL)args[ARG_DISKS];
593 BOOL vols = (BOOL)args[ARG_VOLS];
594 BOOL showall = (BOOL)args[ARG_ALL];
595 BOOL blocks = (BOOL)args[ARG_BLOCKS];
596 STRPTR *devs = (STRPTR *)args[ARG_DEVS];
598 if (devs && (*devs == NULL)) devs = NULL;
600 /* If nothing is specified, show everything we got */
601 if(devs == NULL && !disks && !vols)
603 vols = TRUE;
604 disks = TRUE;
607 /* check pattern strings */
609 if(devs != NULL)
611 STRPTR *p = devs;
613 while(*p != NULL)
615 TEXT matchstr[128];
617 if(ParsePatternNoCase(*p, matchstr, sizeof(matchstr)) == -1)
619 PrintFault(IoErr(), *p);
620 goto end;
623 p++;
627 /* avoid requesters */
628 proc = (struct Process *)FindTask(NULL);
629 win = (struct Window *)proc->pr_WindowPtr;
630 proc->pr_WindowPtr = (struct Window *)~0;
632 MaxLen = strlen(unit);
634 D(bug("Calling ScanDosList()\n"));
636 /* scan doslist */
637 if(ScanDosList(devs))
639 CONST_STRPTR dstate[3] = { GetStrFromCat(READONLY, "read only"),
640 GetStrFromCat(VALIDATING, "validating"),
641 GetStrFromCat(READWRITE, "read/write") };
642 STRPTR datetimeFmt = NULL;
643 BOOL first = TRUE;
644 TEXT nfmtstr[16];
645 TEXT buf[64];
647 D(bug("Printing stuff\n"));
649 /* get datetimefmt string */
650 if(loc && (GetVar("info_datetime", buf, sizeof(buf), 0L) > 0L))
652 datetimeFmt = buf;
655 /* calc format string for 'Unit' */
656 __sprintf(nfmtstr, "%%-%lds", MaxLen);
658 /* show device infomation */
659 if(devs != NULL || disks || !vols)
661 for(idn = head; idn; idn = idn->Next)
663 BPTR lock;
664 STRPTR name = idn->Name;
666 D(bug("Got name = %s\n", name));
668 if(!idn->IsVolume && IsFileSystem(name))
670 BOOL gotinfo = FALSE;
671 /* if first device to print, print title */
672 if(first || blocks)
674 if(!first)
675 Printf("\n");
677 D(bug("Printing device\n"));
679 VLPrintf(~0, nfmtstr, (IPTR*) &unit);
680 VLPrintf(DEVTITLE, " Size Used Free Full Errs State Type Name\n", NULL);
682 first = FALSE;
685 VLPrintf(~0, nfmtstr, (IPTR*) &name);
687 D(bug("Locking \"%s\"\n", name));
688 lock = Lock(name, SHARED_LOCK);
690 D(bug("Lock = %p\n", (APTR)lock));
692 if(lock != BNULL)
694 D(bug("Got lock on %s\n", name));
696 if(Info(lock, id) == DOSTRUE)
698 D(bug("Calling NameFromLock()\n"));
700 if(NameFromLock(lock, name, 108L))
702 LONG len = strlen(name) - 1;
704 if(name[len] == ':')
706 name[len] = '\0';
710 gotinfo = TRUE;
712 UnLock(lock);
714 } else if (IoErr() == ERROR_NO_DISK && idn->Task) {
715 name = NULL;
716 D(bug("Calling ACTION_DISK_INFO\n"));
717 if (DoPkt(idn->Task, ACTION_DISK_INFO, (SIPTR)MKBADDR(id), (SIPTR)BNULL, (SIPTR)BNULL, (SIPTR)BNULL, (SIPTR)BNULL)) {
718 gotinfo = TRUE;
722 if (gotinfo) {
723 ULONG x, y;
725 D(bug("Got info on %s\n", name));
727 if (id->id_DiskType != ID_NO_DISK_PRESENT)
730 x = ComputeKBytes(id->id_NumBlocks, id->id_BytesPerBlock);
731 y = ComputeKBytes(id->id_NumBlocksUsed, id->id_BytesPerBlock);
733 PrintNum(x);
734 PrintNum(y);
735 PrintNum(x - y);
737 if(x > 0xfffff)
739 x >>= 10;
740 y >>= 10;
743 if(x)
745 x = ExtUDivMod32(UDivMod32(UMult32(y, 1000), x), 10, &y);
747 if(y > 4)
748 x++;
750 else
751 x = 0;
753 // y = ((struct DeviceList *)BADDR(id->id_VolumeNode))->dl_DiskType;
755 // if(!y)
756 y = id->id_DiskType;
758 if((idn->DosType & ID_DOS_DISK) != ID_DOS_DISK)
759 y = idn->DosType;
762 IPTR args[] = {
764 id->id_NumSoftErrors,
765 ((id->id_DiskState >= ID_WRITE_PROTECTED) && (id->id_DiskState <= ID_VALIDATED)) ?
766 (IPTR) dstate[id->id_DiskState - ID_WRITE_PROTECTED] : (IPTR) "",
767 (IPTR) GetFSysStr(y),
768 (IPTR) name};
769 VLPrintf(DEVFMTSTR, "%4ld%% %4ld %-11s%-8s%s\n", args);
772 if(blocks)
774 IPTR args[] = {
775 id->id_NumBlocks,
776 id->id_NumBlocksUsed,
777 id->id_NumBlocks-id->id_NumBlocksUsed,
778 id->id_BytesPerBlock};
779 VLPrintf(BLOCKSSTR,
780 "\nTotal blocks: %-10ld Blocks used: %ld\n"
781 " Blocks free: %-10ld Blocksize: %ld\n",
782 args);
784 } else {
786 VLPrintf(~0, " No disk present\n", NULL);
790 else
792 D(bug("Info failure\n"));
793 VLPrintf(~0, "\n", NULL);
797 LONG err = IoErr();
799 /* just ignore PIPEFS */
800 if (err == ERROR_ACTION_NOT_KNOWN)
801 if (strcmp(name, "PIPEFS:") == 0)
802 err = 0;
804 if (err && showall)
806 VLPrintf(~0, nfmtstr, (IPTR*) &name);
807 PrintFault(err, NULL);
814 /* show volumes */
815 if(vols || (!devs && !disks))
817 if(!first)
818 PutStr("\n");
820 VLPrintf(DISKSTITLE, "Volumes\n", NULL);
822 for(MaxLen = 15, idn = head; idn; idn = idn->Next)
824 if(idn->IsVolume)
826 LONG len = strlen(idn->Name);
828 if(len > MaxLen)
829 MaxLen = len;
833 __sprintf(nfmtstr, "%%-%lds%%-10s", MaxLen+1);
835 for(idn = head; idn; idn = idn->Next)
837 if(idn->IsVolume)
839 IPTR args[] = {
840 (IPTR) idn->Name,
841 (IPTR) GetStrFromCat(MOUNTEDSTR, "[Mounted]")};
842 // idn->Task ? GetStrFromCat(MOUNTEDSTR, "[Mounted]") : ""); TODO
843 VLPrintf(VOLNAMEFMTSTR, nfmtstr, args);
845 if(datetimeFmt)
847 UBYTE datestr[128];
848 static struct Hook hook;
850 memset(&hook, 0, sizeof(struct Hook));
852 hook.h_SubEntry = (HOOKFUNC)FmtProcedure;
853 hook.h_Data = datestr;
855 FormatDate(loc, datetimeFmt, &idn->VolumeDate, &hook);
857 PutStr(datestr);
859 else
861 TEXT StrDay[LEN_DATSTRING];
862 TEXT StrDate[LEN_DATSTRING];
863 TEXT StrTime[LEN_DATSTRING];
865 struct DateTime dt;
867 dt.dat_Flags = DTF_SUBST;
868 dt.dat_Format = FORMAT_DOS;
869 dt.dat_StrDay = StrDay;
870 dt.dat_StrDate = StrDate;
871 dt.dat_StrTime = StrTime;
872 dt.dat_Stamp = idn->VolumeDate;
874 if(DateToStr(&dt))
876 if(Strnicmp(StrDate, StrDay, strlen(StrDay)) == 0)
878 dt.dat_Flags = 0L;
879 DateToStr(&dt);
882 IPTR args[] = {(IPTR) StrDay, (IPTR) StrDate, (IPTR) StrTime};
883 VLPrintf(DATEFMTSTR, "created %.3s, %-10s %s", args);
887 PutStr("\n");
892 else
894 PrintFault( ERROR_NO_FREE_STORE, NULL);
897 /* reset window pointer of our process */
898 proc->pr_WindowPtr = win;
900 /* free args */
901 FreeArgs(rdargs);
905 end: /* free allocated memory */
906 FreeVec(id);
907 DeletePool(Pool);
911 ULONG ComputeKBytes(ULONG a, ULONG b)
913 // UQUAD result = UMult64(a, b);
915 UQUAD result = (UQUAD)a * b;
917 return (ULONG)(result >> 10);
921 void FmtProcedure(struct Hook *hook, char a, struct Locale *locale)
923 *((STRPTR)hook->h_Data) = a;
924 hook->h_Data = (STRPTR) hook->h_Data + 1;
928 ULONG ExtUDivMod32(ULONG a, ULONG b, ULONG *mod)
930 *mod = a % b;
932 return a/b;