From 7e0f021a9aec35fd8e6725e87e3313b101d26f5e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 27 Jan 2008 11:37:44 +0100 Subject: Initial import (2.0.2-6) --- reference/C/CONTRIB/SNIP/lsd.c | 265 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100755 reference/C/CONTRIB/SNIP/lsd.c (limited to 'reference/C/CONTRIB/SNIP/lsd.c') diff --git a/reference/C/CONTRIB/SNIP/lsd.c b/reference/C/CONTRIB/SNIP/lsd.c new file mode 100755 index 0000000..b416846 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/lsd.c @@ -0,0 +1,265 @@ +/* +** LSD - A simple directory lister +** A public domain C demo program by Bob Stout +*/ + +#include +#include +#include +#include +#include + +/* For portability, make everything look like MSC 6+ */ + +#if defined(__TURBOC__) + #include + #define _dos_findfirst(f,a,b) findfirst(f,b,a) + #define _dos_findnext(b) findnext(b) + #define find_t ffblk + #define _A_SUBDIR FA_DIREC + #define attrib ff_attrib + #define name ff_name + #define size ff_fsize + #define wr_time ff_ftime + #define wr_date ff_fdate + #define _dos_getdiskfree getdfree + #define diskfree_t dfree + #define avail_clusters df_avail + #define sectors_per_cluster df_sclus + #define bytes_per_sector df_bsec +#else /* assume MSC/QC */ + #include +#endif + +#ifdef TRUE + #undef TRUE +#endif +#ifdef FALSE + #undef FALSE +#endif +#ifdef ERROR + #undef ERROR +#endif + +enum LOGICAL {ERROR = -1, SUCCESS, FALSE = 0, TRUE}; + +#ifndef CAST + #define CAST(new_type,old_object) (*((new_type *)&(old_object))) +#endif + +#define LAST_CHAR(s) (((char *)s)[strlen(s) - 1]) + +struct DOS_TIME { + unsigned int ss : 5; + unsigned int mm : 6; + unsigned int hh : 5; + } ; +#define dos_time(t) CAST(struct DOS_TIME, (t)) + +struct DOS_DATE { + unsigned int da : 5; + unsigned int mo : 4; + unsigned int yr : 7; + } ; +#define dos_date(t) CAST(struct DOS_DATE, (t)) + +/* +** DOS DIR improved work-alike w/ improved formatting & attribute display +** +** supports /W switch +*/ + +main(int argc, char *argv[]) +{ + int i, files = 0, dirs = 0, argptr = 0, errflag = FALSE, cols, drive; + long siz_tot = 0L; + char *p, *fname, *ext, name[13], buf[67], numbuf[12]; + struct find_t ff; +#ifndef __ZTC__ + struct diskfree_t df; +#endif + int one_column(), five_column(); + int (*display)(char *, char *, long, unsigned, unsigned, unsigned) + = one_column; + char *sprintfc(char *, long); + char *capitalize(const char *); + + strcpy(buf, fname = "*.*"); + if(argc != 1) for (i = 1; i < argc; ++i) + { + if ('/' == argv[i][0]) + { + if ('W' == toupper(argv[i][1])) + display = five_column; + else + { + puts("\aUsage: LSD [/W] [file]"); + errflag = TRUE; + } + } + else if (!argptr) + argptr = i; + } + if (argptr) + { + fname = argv[argptr]; + strcpy(buf, fname); + if ('\\' == LAST_CHAR(buf) || ':' == LAST_CHAR(buf)) + strcat(buf, "*.*"); + else + { + if (SUCCESS == _dos_findfirst(buf, _A_SUBDIR, &ff)) + { + if (ff.attrib & _A_SUBDIR && '.' != *ff.name) + { + if ('\\' != LAST_CHAR(buf)) + strcat(buf, "\\"); + strcat(buf, "*.*"); + } + } + else errflag = TRUE; + } + } + if (':' == buf[1]) + drive = toupper(*buf) - '@'; + else drive = 0; + if (!errflag && !(_dos_findfirst(buf, 0xff, &ff))) do + { + siz_tot += ff.size; + if (ff.attrib & _A_SUBDIR) + ++dirs; + else ++files; + strcpy(name, ff.name); + if (NULL != (p = strchr(name, '.')) && p != name) + { + *p = '\0'; + ext = ++p; + } + else ext = ""; + cols = (*display)(name, ext, ff.size, + ff.attrib, ff.wr_date, ff.wr_time); + } while (SUCCESS == _dos_findnext(&ff)); + else + { + fprintf(stderr, "Cannot do directory on '%s'\n", fname); + exit(-1); + } + if (cols) + fputc('\n', stdout); + sprintfc(numbuf,siz_tot); + printf("\n%3d Files totalling %s bytes\n", files, numbuf); + printf("%3d Director%s\n", dirs, (1 == dirs) ? "y" : "ies"); +#ifndef __ZTC__ + _dos_getdiskfree(drive, &df); + sprintfc(numbuf, (long)df.avail_clusters * df.sectors_per_cluster * + df.bytes_per_sector); +#else /* if ZTC */ + sprintfc(numbuf, dos_getdiskfreespace(drive)); +#endif + printf("%s bytes free\n", numbuf); + return 0; +} + +/* +** The single column directory entry display function +*/ + +int one_column(char *name, + char *ext, + long size, + unsigned attribs, + unsigned date, + unsigned time) +{ + register int i, mask; + static char *atr = "RHSVDA", szbuf[12]; + + sprintfc(szbuf, size); + printf("%-8s %-3s %12s ", capitalize(name), capitalize(ext), szbuf); + for (i = 0, mask = 1; i < 6; ++i, mask <<= 1) + { + if (attribs & mask) + fputc(atr[i], stdout); + else fputc('.' , stdout); + } + printf("%4d-%02d-%02d%4d:%02d:%02d\n", + dos_date(date).mo, + dos_date(date).da, + (dos_date(date).yr + 80) % 100, + dos_time(time).hh, + dos_time(time).mm, + dos_time(time).ss); + return 0; +} + +/* +** The five column directory entry display function +*/ + +int five_column(char *name, + char *ext, + long size, + unsigned attribs, + unsigned date, + unsigned time) +{ + static int cols = 0; + + printf("%-8s %-3s%s", capitalize(name), capitalize(ext), + (5 > ++cols) ? " " : ""); + if (0 == (cols %= 5)) + putchar('\n'); + return (cols); +} + +/* +** Display a long int using commas as thousands separators +*/ + +char *sprintfc(char *string, long num) +{ + if (num > 999999L) + { + sprintf(string, "%d,%03d,%03d", + (int)(num / 1000000L), + (int)((num % 1000000L) / 1000L), + (int)(num % 1000L)); + } + else + { + if (num > 999L) + { + sprintf(string, "%d,%03d", + (int)(num / 1000L), + (int)(num % 1000L)); + } + else sprintf(string, "%d", (int)num); + } + return string; +} + +/* +** Capitalize a name or extension in place +*/ + +char *capitalize(const char *string) +{ + int flag = 0; + char *ptr = (char *)string; + + do + { + if (isalpha(*ptr)) + { + if (flag) + *ptr = (char)tolower(*ptr); + else + { + flag = 1; + *ptr = (char)toupper(*ptr); + } + } + else flag = 0; + } while (*++ptr); + return (char *)string; +} -- cgit v1.2.3-54-g00ecf