home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume2 / xbrowser / part02 / scandir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-03  |  10.8 KB  |  418 lines

  1. /* Systems Sciences Laboratory, Webster Research Center */
  2.  
  3. static char *PROGRAM_information[] =
  4. {
  5.     "Copyright (c) 1988 Xerox Corporation.  All rights reserved.",
  6.     "$Header$",
  7.     "$Locker$"
  8. }
  9. ;
  10.  
  11. /*
  12.  * Copyright protection claimed includes all forms and matters of copyrightable
  13.  * material and information now allowed by statutory or judicial lay or
  14.  * herinafter granted, including without limitation, material generated from
  15.  * the software programs which are displayed on the screen such as icons,
  16.  * screen display looks, etc.
  17.  */
  18.  
  19. #include "xfilebrowser.h"
  20.  
  21.  
  22. /**************************
  23. *   local data structures *
  24. **************************/
  25. extern int getfiles();
  26. extern int my_alphasort();
  27. extern int filesizesort();
  28. extern int datesort();
  29.  
  30. static Widget listshell = NULL;
  31. static Widget sortoption;    /* option for sorting files */
  32. static Widget owneroption;    /* print owner or group */
  33. static Widget dottoggle;    /* should dot file be printed */
  34.  
  35. static Widget optioncaller;
  36.  
  37. static int currentsort = 1;
  38. static int currentdotfiles = 0;     /* don't print dot files */
  39. int currentid = 1;     /* 1 = print owner name; 2 = print group name */
  40.  
  41. static short direction = 1;
  42.  
  43. static short disp_option = 0;
  44. typedef int (*intfunc)();
  45.  
  46. static intfunc sortfunc[] = {
  47.     my_alphasort, filesizesort, datesort };
  48.  
  49.  
  50. check_option()
  51. {
  52.     return disp_option;
  53. }
  54.  
  55. XtState GetToggle(w)
  56. Widget w;
  57. {
  58.     XtState toggle;
  59.     Arg arglist[1];
  60.  
  61.     XtSetArg(arglist[0], XtNstate, &toggle);
  62.     XtGetValues(w, arglist, (Cardinal)1);
  63.     return(toggle);
  64. }
  65.  
  66. void SetToggle(w, value)
  67. Widget w;
  68. XtState value;
  69. {
  70.     Arg arglist[1];
  71.  
  72.     XtSetArg(arglist[0], XtNstate, value);
  73.     XtSetValues(w, arglist, (Cardinal)1);
  74. }
  75.  
  76. void DoApply()
  77. {
  78.     currentsort = XtOptionGetSelection(sortoption);
  79.     currentid = XtOptionGetSelection(owneroption);
  80.     reset_ownercache();
  81.  
  82.     if (GetToggle(dottoggle) == XtToggleOn) currentdotfiles = 1;
  83.     else currentdotfiles = 0;
  84.  
  85.     disp_option = 0;
  86.     change_sensitive(optioncaller, TRUE);
  87.     XtPopdown(listshell);
  88. }
  89.  
  90. void DoCancel()
  91. {
  92.     XtState toggle;
  93.  
  94.     /* reset the option dialog window */
  95.     if ( !(currentsort == XtOptionGetSelection(sortoption)) ) 
  96.         /* sorting was modified by user */
  97.        XtOptionSetSelection(sortoption, currentsort);
  98.  
  99.     if ( !(currentid == XtOptionGetSelection(owneroption)) ) 
  100.         /* printing owner/group was modified by user */
  101.        XtOptionSetSelection(owneroption, currentid);
  102.  
  103.         /* reset toggle switch for dot files */
  104.     toggle = GetToggle(dottoggle);
  105.     if (toggle == XtToggleOn && currentdotfiles == 0)
  106.        SetToggle(dottoggle, XtToggleOff);
  107.     else if (toggle == XtToggleOff && currentdotfiles == 1)
  108.        SetToggle(dottoggle, XtToggleOn);
  109.  
  110.     disp_option = 0;
  111.     change_sensitive(optioncaller, TRUE);
  112.     XtPopdown(listshell);
  113. }
  114.  
  115.  
  116. build_listoptions()
  117. {
  118.     Arg popargs[1];
  119.     Widget listpane, listrow1, listrow2, optform;
  120.  
  121.     static Arg paneargs[] = {
  122.        { XtNallowResize, (XtArgVal)True },
  123.     };
  124.     static Arg optformlist[] = {
  125.        {XtNborderWidth, (XtArgVal)0 }
  126.     };
  127.  
  128.     static Arg optionargs[] = { 
  129.        { XtNlabel, (XtArgVal)NULL },
  130.        { XtNorientation,(XtArgVal)XtorientVertical },
  131.        { XtNfromHoriz, (XtArgVal) NULL },
  132.        { XtNfromVert, (XtArgVal) NULL },
  133.        { XtNleft, (XtArgVal) XtChainLeft },
  134.        { XtNright, (XtArgVal) XtChainLeft },
  135.        { XtNtop, (XtArgVal) XtChainTop },
  136.        { XtNbottom, (XtArgVal) XtChainTop }
  137.  
  138.     };
  139.     static XtCallbackRec callbackList[] = { {NULL, NULL}, {NULL, NULL} };
  140.     static Arg toggleargs[] = { 
  141.        { XtNlabel, (XtArgVal)NULL },
  142.        { XtNstate,(XtArgVal)XtToggleOff },
  143.        { XtNfromHoriz, (XtArgVal) NULL },
  144.        { XtNfromVert, (XtArgVal) NULL },
  145.        { XtNleft, (XtArgVal) XtChainLeft },
  146.        { XtNright, (XtArgVal) XtChainLeft },
  147.        { XtNtop, (XtArgVal) XtChainTop },
  148.        { XtNbottom, (XtArgVal) XtChainTop }
  149.  
  150.     };
  151.  
  152.     XtSetArg( popargs[0], XtNborderWidth, 2 );
  153.  
  154.     listshell = XtCreatePopupShell("listshell",
  155.                overrideShellWidgetClass,
  156.             toplevel, popargs, XtNumber(popargs));
  157.  
  158.     listpane = XtCreateManagedWidget( "listpaned", vPanedWidgetClass, 
  159.             listshell, paneargs , XtNumber(paneargs) );
  160.     listrow1 = XtCreateManagedWidget("listrow1", boxWidgetClass, 
  161.             listpane, NULL,0);
  162.     listrow2 = XtCreateManagedWidget("listrow2", boxWidgetClass, 
  163.             listpane, NULL,0);
  164.     makeCommandButton(listrow1, "Apply", DoApply);
  165.     makeCommandButton(listrow1, "Cancel", DoCancel);
  166.  
  167.     optform = XtCreateManagedWidget("sorting",formWidgetClass, 
  168.         listrow2, optformlist, XtNumber(optformlist));
  169.  
  170.         /* define option menu for sorting files */
  171.     optionargs[0].value = (XtArgVal)"Select Sorting Option:";
  172.     sortoption = XtCreateManagedWidget("sorting", optionWidgetClass, 
  173.         optform, optionargs, XtNumber(optionargs));
  174.     XtOptionAddOption(sortoption, "File Name", TRUE);
  175.     XtOptionAddOption(sortoption, "File Size", FALSE);
  176.     XtOptionAddOption(sortoption, "Date", FALSE);
  177.  
  178.         /* define option menu for printing owner/group */
  179.     optionargs[0].value = (XtArgVal)"Print Owner/Group Name:";
  180.     optionargs[2].value = (XtArgVal)sortoption;
  181.     owneroption = XtCreateManagedWidget("owner", optionWidgetClass, 
  182.         optform, optionargs, XtNumber(optionargs));
  183.     XtOptionAddOption(owneroption, "Owner Name", TRUE);
  184.     XtOptionAddOption(owneroption, "Group name", FALSE);
  185.  
  186.         /* define toggle for printing . files */
  187.     toggleargs[0].value = (XtArgVal)"Print Dot Files";
  188.     toggleargs[3].value = (XtArgVal)sortoption;
  189.     dottoggle = XtCreateManagedWidget("owner", toggleWidgetClass, 
  190.         optform, toggleargs, XtNumber(toggleargs));
  191.  
  192.     XtSetMappedWhenManaged(listshell, FALSE);
  193.     XtRealizeWidget(listshell);
  194. }
  195.  
  196. display_listoptions(caller)
  197. Widget caller;
  198. {
  199.     if (listshell == NULL) {
  200.        build_listoptions();
  201.        optioncaller = caller;
  202.     }
  203.  
  204.     disp_option = 1;
  205.     move_popup(listshell, caller);
  206.     change_sensitive(caller, FALSE);
  207.     XtMapWidget(listshell);
  208.     XtPopup(listshell, XtGrabNonexclusive);
  209. }
  210.  
  211. /*********************************
  212. * routines for scanning the directory *
  213. ***********************************/
  214.  
  215. free_direct(dfiles, numdfiles)
  216. struct afile ***dfiles;
  217. int *numdfiles;
  218. {
  219.     register int i;
  220.     register struct afile **listfiles = *dfiles;
  221.  
  222.     if (listfiles != (struct afile **)NULL) {
  223.        for (i = 0; i < *numdfiles; i++) free(listfiles[i]);
  224.        *numdfiles = 0;
  225.        free(listfiles);
  226.        *dfiles = (struct afile **)NULL;
  227.     }
  228. }
  229.  
  230.  
  231. /* ARGSUSED */
  232. int prepare_list(dirname, dir, dfiles, numdfiles, nameprepend)
  233. char * dirname;
  234. short dir;
  235. struct afile ***dfiles;
  236. int *numdfiles;
  237. char *nameprepend;
  238. {
  239.     if (dir != 0) direction = dir;
  240.     if ( (*numdfiles = my_scandir(dirname, dfiles, getfiles,
  241.              sortfunc[currentsort-1], nameprepend) ) < 0) {
  242.        disp_message("\nList: current directory?");
  243.        return (-1);
  244.     }
  245.     return(0);
  246. }
  247.  
  248. /* ARGSUSED */
  249. getfiles(dp)
  250. register struct direct *dp;
  251. {
  252.     if (!currentdotfiles && (dp->d_name)[0] == '.') return 0;
  253.     if (! strcmp(dp->d_name, ".") ||  ! strcmp(dp->d_name, "..")) return 0;
  254.     if (re_exec(dp->d_name)) return 1;
  255.     else return 0;
  256. }
  257.  
  258. /* ARGSUSED */
  259. my_scandir(dirname, namelist, select, dcomp, nameprepend)
  260. char *dirname;
  261. struct afile *(*namelist[]);
  262. int (*select)(), (*dcomp)();
  263. char *nameprepend;
  264. {
  265.     register struct direct *d;
  266.     register struct afile *p, **names;
  267.     register int j;
  268.     int nitems, cc;
  269.     register char *cp1, *cp2;
  270.     struct stat stb;
  271.     struct stat fbuf;
  272.     u_short elemlength;
  273.     long arraysz;
  274.     DIR *dirp;
  275.     char path[MAXNAME + 1];
  276.     int prelength = (nameprepend == NULL) ? 0 : (strlen(nameprepend)+1);
  277.  
  278.     if ((dirp = opendir(dirname)) == NULL)
  279.         return(-1);
  280.     if (fstat(dirp->dd_fd, &stb) < 0)
  281.         return(-1);
  282.  
  283.     /*
  284.      * estimate the array size by taking the size of the directory file
  285.      * and dividing it by a multiple of the minimum size entry. 
  286.      */
  287.     arraysz = (stb.st_size / 24);
  288.     names = (struct afile **)XtMalloc(arraysz * sizeof(struct afile *));
  289.  
  290.     nitems = 0;
  291.     while ((d = readdir(dirp)) != NULL) {
  292.        if (select != NULL && !(*select)(d))
  293.         continue;    /* just selected names */
  294.         /*
  295.          * Make a minimum size copy of the data
  296.          */
  297.        elemlength = MYDIRSIZ(d, prelength);
  298.        p = (struct afile *)XtMalloc(elemlength);
  299.        p->d_marked = 0;
  300.        p->d_ino = d->d_ino;
  301.        p->d_reclen = elemlength;
  302.        p->d_namlen = d->d_namlen + prelength;
  303.        sprintf(path, "%s/%s", dirname, d->d_name);
  304.  
  305.        if (nameprepend != (char *)NULL) {
  306.            for (cp1 = p->d_name, cp2 = nameprepend; 
  307.                         *cp1++ = *cp2++; );
  308.         *(cp1 - 1) = '/';
  309.            for (cp2 = d->d_name; *cp1++ = *cp2++; );
  310.            if (stat(path, &fbuf) ) return(-1);
  311.             /* no stats file is found */
  312.        }
  313.        else {
  314.         for (cp1 = p->d_name, cp2 = d->d_name; *cp1++ = *cp2++; ); 
  315.  
  316.            if (lstat(path, &fbuf) ) {
  317.            disp_message("\nList: stats file for %s", d->d_name);
  318.            return(-1);
  319.            }
  320.        }
  321.  
  322.        p->d_size = fbuf.st_size;
  323.        p->d_nlink = fbuf.st_nlink;
  324.  
  325.        switch(fbuf.st_mode & S_IFMT) {
  326.        case S_IFDIR:  p->d_type = 'd'; break;
  327.        case S_IFBLK:  p->d_type = 'b'; p->d_size = fbuf.st_rdev; break;
  328.        case S_IFCHR:  p->d_type = 'c'; p->d_size = fbuf.st_rdev; break;
  329.        case S_IFSOCK: p->d_type = 's'; p->d_size = 0; break;
  330.        case S_IFLNK:  p->d_type = 'l'; break;
  331.        default:       p->d_type = '-'; break;
  332.        }
  333.  
  334.        j = 0;
  335.        if (fbuf.st_mode & 0400) 
  336.         p->d_access[j++] = 'r'; else p->d_access[j++] = '-';
  337.        if (fbuf.st_mode & 0200) 
  338.         p->d_access[j++] = 'w'; else p->d_access[j++] = '-';
  339.        if (fbuf.st_mode & 0100) 
  340.         p->d_access[j++] = 'x'; else p->d_access[j++] = '-';
  341.        if (fbuf.st_mode & 0040) 
  342.         p->d_access[j++] = 'r'; else p->d_access[j++] = '-';
  343.        if (fbuf.st_mode & 0020) 
  344.         p->d_access[j++] = 'w'; else p->d_access[j++] = '-';
  345.        if (fbuf.st_mode & 0010) 
  346.         p->d_access[j++] = 'x'; else p->d_access[j++] = '-';
  347.        if (fbuf.st_mode & 0004) 
  348.         p->d_access[j++] = 'r'; else p->d_access[j++] = '-';
  349.        if (fbuf.st_mode & 0002) 
  350.         p->d_access[j++] = 'w'; else p->d_access[j++] = '-';
  351.        if (fbuf.st_mode & 0001) 
  352.         p->d_access[j++] = 'x'; else p->d_access[j++] = '-';
  353.        p->d_access[j] = '\0';
  354.  
  355.        p->d_ctime = fbuf.st_ctime;
  356.        p->d_uid = fbuf.st_uid;
  357.        p->d_gid = fbuf.st_gid;
  358.  
  359.         /*
  360.          * Check to make sure the array has space left and
  361.          * realloc the maximum size.
  362.          */
  363.        if (++nitems >= arraysz) {
  364.         if (fstat(dirp->dd_fd, &stb) < 0)
  365.                 return(-1);    /* just might have grown */
  366.         arraysz = stb.st_size / 12;
  367.         names = (struct afile **)XtRealloc((char *)names,
  368.                 arraysz * sizeof(struct afile *));
  369.        }
  370.        names[nitems-1] = p;
  371.     }
  372.     closedir(dirp);
  373.     if (nitems && dcomp != NULL)
  374.         qsort(names, nitems, sizeof(struct afile *), dcomp);
  375.     *namelist = names;
  376.     return(nitems);
  377. }
  378.  
  379. /*
  380.  * Alphabetic order comparison routine
  381.  */
  382. /* ARGSUSED */
  383. int my_alphasort(d1, d2)
  384.     struct afile **d1, **d2;
  385. {
  386.     return(direction * strcmp((*d1)->d_name, (*d2)->d_name));
  387. }
  388.  
  389. /*
  390.  * file size order comparison routine
  391.  */
  392. /* ARGSUSED */
  393. int filesizesort(d1, d2)
  394.     struct afile **d1, **d2;
  395. {
  396.     int i;
  397.  
  398.     if ( (*d1)->d_size < (*d2)->d_size ) i = (int)direction * (-1);
  399.     else if ( (*d1)->d_size > (*d2)->d_size ) i = (int)direction;
  400.     else i = 0;
  401.     return(i);
  402. }
  403.  
  404. /*
  405.  * file date order comparison routine
  406.  */
  407. /* ARGSUSED */
  408. int datesort(d1, d2)
  409.     struct afile **d1, **d2;
  410. {
  411.     int i;
  412.  
  413.     if ( (*d1)->d_ctime < (*d2)->d_ctime ) i = (int)direction * (-1);
  414.     else if ( (*d1)->d_ctime > (*d2)->d_ctime ) i = (int)direction;
  415.     else i = 0;
  416.     return(i);
  417. }
  418.