⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getsdir.c

📁 在MAC OS下的一个可以直接调试modem的工具minicom,类似于是在windows下的超级终端.
💻 C
字号:
/* * getsdir.c * *	Get and return a sorted directory listing * *	Copyright (c) 1998 by James S. Seymour (jseymour@jimsun.LinxNet.com) * *	This code is free software; you can redistribute it and/or *	modify it under the terms of the GNU General Public License *	as published by the Free Software Foundation; either version *	2 of the License, or (at your option) any later version. * *  You should have received a copy of the GNU General Public License along *  with this program; if not, write to the Free Software Foundation, Inc., *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *	Note: this code uses "wildmat.c", which has different copyright *	and licensing conditions.  See the source, Luke. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "rcsid.h"RCSID("$Id: getsdir.c,v 1.5 2007-10-10 20:18:20 al-guest Exp $")#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include "getsdir.h"#include "intl.h"#include "minicom.h"/* locally defined constants */#define MAX_CNT 100		/* number of entries to hold in holding buf */typedef struct dat_buf {		/* structure of input buffers */  struct dat_buf *nxt;			/* pointer to next buffer */  unsigned cnt;				/* data count in present buffer */  GETSDIR_ENTRY data[MAX_CNT];		/* data in present buffer */} DAT_BUF;static DAT_BUF *datb_frst;		/* pointer to first data buffer */static DAT_BUF *datb_cur;		/* pointer to current data buffer */static int g_sortflags;			/* sort flags *//* sort compare routines */static int namecmpr(GETSDIR_ENTRY *d1, GETSDIR_ENTRY *d2);static int timecmpr(GETSDIR_ENTRY *d1, GETSDIR_ENTRY *d2);static void free_up(void);	/* free-up used memory *//* * name:	getsdir * * purpose:	To return a directory listing - possibly sorted * * synopsis:	#include <dirent.h> * *		int getsdir(dirpath, pattern, sortflags, modemask, datptr, len) *		const char *dirpath; *		const char *pattern; *		int sortflags; *		mode_t modemask; *		GETSDIR_ENTRY **datptr; *		int *len; * * input:	 *dirpath - pointer to path to directory to get list of *			    files from *		 *pattern - pointer to optional wildmat pattern *		sortflags - specification flags of how to sort the *			    resulting list.  See descriptions below. *		 modemask - caller-supplied mode mask.  Bits in this will *			    be ANDed against directory entries to determine *			    whether to return them.  Ignored if 0. *		 **datptr - pointer to a destination pointer variable. *			    getsdir will allocate the required amount *			    of memory for the results and will return a *			    pointer to the returned data in this variable. * *			    The data will be in the form: *				typedef struct dirEntry { *				    char fname[MAXNAMLEN + 1]; *				    time_t time; *				    mode_t mode; *				} GETSDIR_ENTRY; *		     *len - pointer to int to contain length of longest *			    string in returned array. * * process:	For each 0..MAX_CNT values read from specified directory, *		allocates a temporary buffer to store the entries into. *		When end of directory is detected, merges the buffers into *		a single array of data and sorts into order based on key. * * output:	Count of number of data items pointed to by datptr or *		-1 if error.  errno may or may not be valid, based on *		type of error encountered. * * notes:	If there is any error, -1 is returned. * *		It is the caller's responsibility to free the memory *		block pointed to by datptr on return when done with the *		data, except in case of error return. * *		See also: opendir(3C), readdir(3C), closedir(3C), qsort(3C) * *		The pattern parameter is optional and may be 0-length or *		a NULL pointer. * *		The sort flags affect the output as follows: * *		    GETSDIR_PARNT - include parent dir (..) *		    GETSDIR_NSORT - sort by name *		    GETSDIR_TSORT - sort by time (NSORT wins if both) * *		    The following are only meaningful if GETSDIR_NSORT or *		    GETSDIR_TSORT are specified: * *			GETSDIR_DIRSF - dirs first *			GETSDIR_DIRSL - dirs last *			GETSDIR_RSORT - reverse sort (does not affect *					GETSDIR_DIRSF/GETSDIR_DIRSL) * *		So-called "hidden" files (those beginning with a ".") are *		not returned unless a pattern like ".*" is specified. * *		The present directory (".") is never returned. */int getsdir(const char *dirpath, const char *pattern, int sortflags,            mode_t modemask, GETSDIR_ENTRY **datptr, int *len){  unsigned cnt;		/* data count */  DIR *dirp;			/* point to open dir */  struct dirent *dp;		/* structure of dir as per system */  struct stat statbuf;	/* structure of file stat as per system */  char fpath[BUFSIZ];		/* filename with dir path prepended */  int indx;			/* g-p array indexer */  int cmprstat;  DAT_BUF *datb_sav;		/* pointer to previous data buffer */  g_sortflags = sortflags;		/* for sort funcs */  *len = 0;				/* longest name */  datb_frst = (DAT_BUF *) NULL;		/* init pointers to first data buff */  datb_cur  = (DAT_BUF *) NULL;  /* open the specified directory */  if ((dirp = opendir(dirpath)) == NULL)    return -1;  for (cnt = 1; ; ++cnt) {        /* for buffer count 1 to whatever... */    datb_sav = datb_cur;	/* save pointer to previous buffer */    /* get a new buffer */    if ((datb_cur = calloc(1, sizeof(DAT_BUF))) == NULL) {      closedir(dirp);      return -1;    }    /* init new buffer link pointer */    datb_cur->nxt = NULL;    if (datb_frst == NULL)		/* if first buff... */      datb_frst = datb_cur;		/* ...init first buff pointer */    else				/* else... */      datb_sav->nxt = datb_cur;		/* ...link to new */    /* while the current buffer is not full, get directory entries */    for (datb_cur->cnt = 0; datb_cur->cnt < MAX_CNT;)      if ((dp = readdir(dirp))) {/* get next directory entry */	if (!strcmp(dp->d_name, "."))	  continue;        if ((sortflags & GETSDIR_PARNT) && !strcmp(dp->d_name, ".."))          cmprstat = 1;        else if (pattern && strlen(pattern))          cmprstat = wildmat(dp->d_name, pattern);        else          cmprstat = 1;        if (cmprstat) {			/* matching name? */          int l;          /* copy the filename */          strncpy(datb_cur->data[datb_cur->cnt].fname, dp->d_name, MAXNAMLEN);          /* get information about the directory entry */          snprintf(fpath, sizeof(fpath), "%s/%s", dirpath, dp->d_name);          if (stat(fpath, &statbuf)) {	/* if error getting stat... */#if 0            free_up();		/* free-up used memory */            closedir(dirp);	/* close file pointer */            return -1;		/* nobody home */#endif            continue;          }          if (modemask && !(S_IFMT & modemask & statbuf.st_mode))            continue;          if ((l = strlen(dp->d_name)) > *len)            *len = l;          datb_cur->data[datb_cur->cnt].time = statbuf.st_mtime;          datb_cur->data[datb_cur->cnt].mode = statbuf.st_mode;          ++datb_cur->cnt;	/* bump array index / data count */        }      }      else        break;			/* at end of directory */    if (datb_cur->cnt < MAX_CNT)/* if less than full buffer... */      break;			/* ...all done */  }  closedir(dirp);		/* close file pointer */  /* get memory for single array */  if ((*datptr = (GETSDIR_ENTRY *)calloc(cnt, sizeof(datb_cur->data))) == NULL) {    /* couldn't get space, clear everything up */    free_up();		/* free-up used memory */    return -1;		/* error */  }  /* copy/concatenate the data */  cnt = indx = 0;		/* init final count and dest index */  do {    datb_cur = datb_frst;    /* copy data in one swell foop */    memcpy(*datptr+indx * MAX_CNT, datb_cur->data, sizeof(datb_cur->data));    cnt += datb_cur->cnt;	/* adjust data count */    ++indx;			/* bump destination index */    datb_frst = datb_cur->nxt;    free(datb_cur);		/* free no longer needed buffer */  } while (datb_frst);          /* while more to go */  free_up();	/* free-up used memory */  /* post-process array by option */  if (cnt && sortflags) {    if (sortflags & GETSDIR_NSORT)      qsort(*datptr, cnt, sizeof(GETSDIR_ENTRY),            (int (*)(const void *, const void *))namecmpr);    else if (sortflags & GETSDIR_TSORT)      qsort(*datptr, cnt, sizeof(GETSDIR_ENTRY),            (int (*)(const void *, const void *))timecmpr);  }  return cnt;} /* getsdir *//* * name:	free_up * * purpose:	free up memory allocated for temporary buffers * * synopsis:	static void freeup() * * input:	none * * process:	as under purpose * * output:	none * * notes:	none */static void free_up(void){  if ((datb_cur = datb_frst) != NULL)	/* start with first */    do {                                /* and free 'em all */      datb_frst = datb_cur->nxt;      free(datb_cur);    } while ((datb_cur = datb_frst));} /* free_up *//* * name:	namecmpr * * purpose:	return stat to qsort on comparison between name fields in *		directory entry. * * synopsis:	static in namecmpr(d1, d2) *		GETSDIR_ENTRY *d1; *		GETSDIR_ENTRY *d2; * * input:	See explanation of qsort * * process:	See explanation of qsort * * output:	See explanation of qsort * * notes:	See explanation of qsort */static int namecmpr(GETSDIR_ENTRY *d1, GETSDIR_ENTRY *d2){  if (g_sortflags & (GETSDIR_DIRSF | GETSDIR_DIRSL)) {    if (S_ISDIR((d1->mode)) && !S_ISDIR((d2->mode)))      return (g_sortflags & GETSDIR_DIRSF) ? -1 : 1;    else if (S_ISDIR((d2->mode)) && ! S_ISDIR((d1->mode)))      return (g_sortflags & GETSDIR_DIRSF) ? 1 : -1;  }  return (g_sortflags & GETSDIR_RSORT)          ? strcmp(d2->fname, d1->fname) : strcmp(d1->fname, d2->fname);} /* namecmpr *//* * name:	timecmpr * * purpose:	return stat to qsort on comparison between time fields in *		directory entry. * * synopsis:	static in timecmpr(d1, d2) *		GETSDIR_ENTRY *d1; *		GETSDIR_ENTRY *d2; * * input:	See explanation of qsort * * process:	See explanation of qsort * * output:	See explanation of qsort * * notes:	See explanation of qsort */static int timecmpr(GETSDIR_ENTRY *d1, GETSDIR_ENTRY *d2){  if (g_sortflags & (GETSDIR_DIRSF | GETSDIR_DIRSL)) {    if (S_ISDIR((d1->mode)) && !S_ISDIR((d2->mode)))      return (g_sortflags & GETSDIR_DIRSF) ? -1 : 1;    else if (S_ISDIR((d2->mode)) && ! S_ISDIR((d1->mode)))      return (g_sortflags & GETSDIR_DIRSF) ? 1 : -1;  }  return (g_sortflags & GETSDIR_RSORT)         ? (d2->time - d1->time) : (d1->time - d2->time);} /* timecmpr */#ifdef GETSDIR_STANDALONE_TEST/* * debug for getsdir() * * usage: getsdir <dirpath> * */extern char *ctime(void);void main(int argc, char **argv){  GETSDIR_ENTRY *dirdat;  int cnt, index;  int sortflags = 0;  mode_t modemask = (mode_t) 0;  int len;  if (argc != 4) {    fprintf(stderr,"usage: %s <dirpath> <pattern> <sortflags>\n", argv[0]);    exit(1);  }  switch (argv[3][0]) {    case 'n': sortflags = GETSDIR_NSORT;              break;    case 't': sortflags = GETSDIR_TSORT;              break;  }  /* sortflags |= GETSDIR_DIRSL | GETSDIR_RSORT; */  sortflags |= GETSDIR_DIRSF;  /* sortflags |= GETSDIR_PARNT; */  /* modemask = S_IFDIR | S_IFREG; */  printf("modemask==%x\n", modemask);  if ((cnt = getsdir(argv[1], argv[2], sortflags, modemask, &dirdat, &len)) == -1) {    fprintf(stderr, "%s: error getting directory\n", argv[0]);    exit(1);  }  printf(_("%d files:\n"), cnt);  for (index = 1; index <= cnt; ++index, ++dirdat)    printf("%2d: %-20s%s", index, dirdat->fname, ctime(&dirdat->time));  free(dirdat);  return 0;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -