home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / pocketbk / comms / x_sun_psio / code / psbackup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-20  |  23.9 KB  |  818 lines

  1. /* (C) Tim Graves 20th April 1994
  2.    This code is supplied AS IS. no warrantee either expressed or implied 
  3.    is provided. This code may be freeley modified and modified as long as my
  4.    origional authorship is acknowledged. 
  5.    
  6.    Tim Graves
  7.     Sun Microsystems
  8.      
  9.      */
  10. /* this module performs a backup of the files on the psion under path and stores it in backup, no input filtering is done (VAR_FILEFILT) is removed)*/
  11.  
  12. #include <stdio.h>
  13. #include <ctype.h>
  14. #include <string.h>
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include "psion.h"
  18. #include "psbackup.h"
  19. static char vsn[] = "@(#) psbackup.c 3.6@(#)" ;
  20. struct backupentry * backhead ;
  21. int debugbackup = FALSE ;
  22. int incremental = FALSE ;
  23. extern int debugcall ;
  24. int filecount, dircount ;
  25. psrlist(path, fd)
  26. char * path ;
  27. FILE * fd ;
  28. {
  29.     if (debugcall >= BACKUPCALLDEBUG)
  30.         fprintf(stderr, "CALL: psrlist (path = %s)\n", path) ;
  31.     if (findvar(VAR_VERBOSE) != NULL)
  32.         printf("Generating a recursive listing of %s\n",path) ;
  33.     /* force the incremental flag to be false as this is a listing */
  34.     incremental = FALSE ;
  35.     lowerpath(path) ;
  36.     initbackuplist(path) ;
  37.     backuplist(backhead,FALSE,"", "") ;
  38.     printbackuplist(backhead, fd) ;
  39.     closebackuplist(backhead) ;
  40. }
  41.  
  42. psbackup(path,backupdir, incr)
  43. char * path,* backupdir ;
  44. {
  45.     int filefilterwasset; 
  46.     int ch ;
  47.     time_t timestart, timeend ;
  48.     if (debugcall >= BACKUPCALLDEBUG)
  49.         fprintf(stderr, "CALL: psbackup (path = %s, backupdir = %s, incr = %d)\n", path, backupdir, incr) ;    
  50.         
  51.     /* if backupnocheck is set dont ask the user to close all the files
  52.        This is potentialy dangerous as suncom can't get a file if it is
  53.        open */
  54.     if (findvar(VAR_BACKUPNOCHECK) == NULL)
  55.     {
  56.         /* ask the user to ensure that all open files on the psion are closed */
  57.         printf("BACKUP: Please ensure that all files on the psion are closed\n");
  58.         printf("BACKUP: Press return to continue\n");
  59.         ch = getchar();
  60.     }
  61.     /* is this incremental ? */
  62.     incremental = incr ;
  63.     /* reset the file/dir counts */
  64.     filecount = 0 ;
  65.     dircount = 0 ;
  66.     /* get the start time */
  67.     timestart = time(NULL) ;
  68.     if (findvar(VAR_VERBOSE) != NULL)
  69.     {
  70.         printf("BACKUP: Starting %sbackup of %s to %s\n", incremental ? "incremental " : "", path,backupdir);
  71.         printf("BACKUP: %s\n", ctime(×tart)) ;
  72.         printf("BACKUP: Stage 1, Building file list\n");
  73.     }
  74.     lowerpath(path) ;
  75.     initbackuplist(path) ;
  76.     /* was VAR_FILEFILT set ? if so unsetit */
  77.     if (findvar(VAR_FILEFILT) != NULL)
  78.     {
  79.         filefilterwasset=TRUE ;
  80.         delvar(VAR_FILEFILT) ;
  81.     }
  82.     /* build a list of files to backup using the excludlist*/
  83.     backuplist(backhead,TRUE, backupdir, path) ;
  84.     /* do the backup */
  85.     if (findvar(VAR_VERBOSE) != NULL)
  86.         printf("BACKUP: Stage 2, Getting files\n");
  87.     dobackup(backupdir,backhead, path) ;
  88.     /* free the accumulated data structures */
  89.     closebackuplist(backhead) ;
  90.     /* reset the VAR_FILEFILT if it was set */
  91.     if (filefilterwasset)
  92.         addvar(VAR_FILEFILT,"")  ;
  93.     timeend = time(NULL) ;
  94.     if (findvar(VAR_VERBOSE) != NULL)
  95.     {
  96.         printf("BACKUP: %s of %s to %s complete\n", incremental ? "Incremental backup" : "Backup", path, backupdir) ;
  97.         printf("BACKUP: %s\n", ctime(&timeend)) ;
  98.         printf("BACKUP: %d directories, %d files\n", dircount, filecount) ;
  99.         printf("BACKUP: Time taken %d seconds\n", (int) timeend - timestart) ;
  100.     }
  101.         
  102. }
  103. backuplist(currnode,exclude, backupdir, psionpath)
  104. struct backupentry *currnode ;
  105. int exclude ;
  106. char * backupdir, *psionpath ;
  107. {
  108.     int i ;
  109.     char tmp[100],  nodepath[1024];
  110.     FILE * fd ;
  111.     struct backupentry *child ;
  112.     int nodepathlen ;
  113.     if (debugcall >= BACKUPCALLDEBUG)
  114.         fprintf(stderr, "CALL: backuplist (currnode->pname = %s, exclude = %d, backupdir = %s, psionpath= %s)\n", currnode->pname, exclude, backupdir, psionpath) ;    
  115.     /* are we using the excludelist ? if so is thie item on it ? */
  116.     if (exclude)
  117.     {
  118.         if (currnode->exclude = findexclude(currnode->pname))
  119.             return ;
  120.     }
  121.     /* if the current node is a file set the flg and and check
  122.        that the file mod has not changed, if so exclude it */
  123.     if ((currnode->nodetype=backuppathtype(currnode->pname)) == BACKUPNODEFILE)
  124.     {
  125.         if (incremental)
  126.             currnode->exclude = backupmodified(currnode->pname,backupdir, psionpath) ;
  127.         return ;
  128.     }
  129.     /* the current node is a directory, Lets work on it */
  130.     /* build up the list command */
  131.     strcpy(tmp, "list ");
  132.     strcat(tmp,currnode->pname) ;
  133.     /* remember we need a \ to make the search work */
  134.     strcat(tmp,"\\");
  135.     strcat(tmp," ");
  136.     strcat(tmp,BACKUPLISTNAME) ;
  137.     /* list the current node use cmdintr to do the work ! */
  138.     cmdintr(tmp) ;
  139.     /* we now have a list in BACKUPLISTNAME of all the items in this node lets get them !*/
  140.     if ((fd = fopen(BACKUPLISTNAME,"r")) == NULL)
  141.     {
  142.         printf("ERROR: Error in opening backup temporary file quiting\n") ;
  143.         psdc() ;
  144.     }
  145.     while (fgets(nodepath,120,fd) != NULL)
  146.     /* for each item in the current node */
  147.     {
  148.         /* if the last char is newline, removeit, cmdintr
  149.             doesnot like it */
  150.         nodepathlen = strlen(nodepath) ;
  151.         if (nodepath[nodepathlen -1] == '\n')
  152.             nodepath[nodepathlen -1] = 0 ;
  153.         if (debugbackup)
  154.             printf("Now working on %s\n", nodepath) ;
  155.         /* create a new node and install its name */
  156.         lowerpath(nodepath) ;
  157.         backupaddchild(currnode,nodepath) ;
  158.     }
  159.     fclose(fd) ;
  160.     /* remove the tmp file so others running the program won't 
  161.        have a problem */
  162.     if (unlink (BACKUPLISTNAME))
  163.         printf("ERROR: Error in removing backup temporary file\n") ;
  164.     /* get ready to scan the children in the current node */
  165.     child = currnode->children ;    
  166.     /* for each item in the current node */
  167.     while(child != NULL)
  168.     {
  169.         /* recursively call backuplist to work on the new item */
  170.         backuplist(child,exclude, backupdir, psionpath) ;
  171.         child = child->next ;
  172.     }
  173. }
  174. backuppathtype(path)
  175. char * path ;
  176. {
  177.     int atts ;
  178.     pssetpath(path) ;
  179.     atts = psgetatts() ;
  180.     if (atts & PSFILEDIR)
  181.         return(BACKUPNODEDIR) ;
  182.     else
  183.         return(BACKUPNODEFILE );
  184. }
  185. struct backupentry * backupnode(path) 
  186. char * path ;
  187. {
  188.     int i ;
  189.     struct backupentry * ret ;
  190.     if (debugcall >= BACKUPCALLDEBUG)
  191.         fprintf(stderr, "CALL: backupentry (path = %s)\n", path) ;
  192.     /* create the ctructure */
  193.     ret = (struct backupentry *) calloc (1,sizeof(struct backupentry)) ;
  194.     /* fill in the name */
  195.     ret->pname = (char *) calloc(1,strlen(path) +1) ;
  196.     strcpy(ret->pname,path) ;
  197.     /* ensure that we done know what type of node this is */
  198.     ret->nodetype = BACKUPNODEUNKNOWN ;
  199.     /* initialy thie node is not excluded */
  200.     ret->exclude = FALSE ;
  201.     /* initialy this node has no children */
  202.     ret->children = NULL ;
  203.     /* initialy there is no next pointer */
  204.     ret->next = NULL ;
  205.     if (debugbackup)
  206.         printf("BACKUP: adding %s\n", path) ;
  207.     return (ret) ;
  208. }
  209.  
  210. initbackuplist(path)
  211. char * path ;
  212. {
  213.     /* create the first entry */
  214.     if (debugcall >= BACKUPCALLDEBUG)
  215.         fprintf(stderr, "CALL: initbackuplist ()\n") ;
  216.     backhead = backupnode(path) ;
  217. }
  218. backupaddchild(currnode,nodepath) 
  219. char * nodepath ;
  220. struct backupentry * currnode ;
  221. {
  222.     struct backupentry * tmp ;
  223.     if (debugcall >= BACKUPCALLDEBUG)
  224.         fprintf(stderr, "CALL: backupaddchild (currnode->pname, nodepath = %s)\n", currnode->pname, nodepath) ;
  225.     /* create the node - note -> next is initialised to NULL */
  226.     tmp = backupnode(nodepath) ;
  227.     /* insert the new node into the head of the list of children in the current node */
  228.     tmp->next = currnode->children ;
  229.     currnode->children = tmp ;
  230. }
  231. closebackuplist (currnode)
  232. struct backupentry * currnode ;
  233. {
  234.     struct backupentry * child, *nextchild ;
  235.     if (debugcall >= BACKUPCALLDEBUG)
  236.         fprintf(stderr, "CALL: closebackuplist (currnode->pname = %s)\n", currnode->pname) ;
  237.     /* for each entry in the current node kill the children */
  238.     child = currnode->children ;
  239.     while(child != NULL)
  240.     {
  241.         /* save a pointer to the next child otherwise we will be referencing through freed data */
  242.         nextchild = child -> next ;
  243.         closebackuplist(child) ;
  244.         child = nextchild ;
  245.     }    
  246.     /* no children left, free ourselves */
  247.     free(currnode->pname) ;
  248.     free (currnode) ;
  249. }
  250. printbackuplist(currnode, fd)
  251. struct backupentry * currnode ;
  252. FILE * fd ;
  253. {
  254.     struct backupentry *child ;
  255.     int i ;
  256.     if (debugcall >= BACKUPCALLDEBUG)
  257.         fprintf(stderr, "CALL: printbackuplist (currnode->pname = %s)\n", currnode->pname) ;
  258.  
  259.     /* print the curent node name and then do eack of the children */
  260.     if ( fd == NULL)
  261.         printf("%s\n",currnode->pname) ;
  262.     else
  263.         fprintf(fd, "%s\n", currnode->pname) ;
  264.         
  265.     /* for each entry in the current print the children */
  266.     child = currnode->children ;
  267.     while (child != NULL)
  268.     {
  269.         printbackuplist(child, fd) ;
  270.         child = child->next ;
  271.     }
  272.     /* no children left return */
  273.     return ;
  274. }
  275. dobackup(path,currnode, psionpath)
  276. char * path, *psionpath ;
  277. struct backupentry * currnode ;
  278. {
  279.     int i ;
  280.     char * tmp ;
  281.     char resp [10] ;
  282.     char targetpath [1024] ;
  283.     char cmd[2048] ;
  284.     struct backupentry * child ;
  285.     if (debugcall >= BACKUPCALLDEBUG)
  286.         fprintf(stderr, "CALL: dobackup (path = %s, currnode->pname = %s, psionpath= %s)\n",path, currnode->pname, psionpath) ;
  287.     /* check that the current node is not excluded */
  288.     if (currnode->exclude)
  289.         return ;
  290.  
  291.     /* if the current entry is a file get it and return */
  292.     if (currnode->nodetype == BACKUPNODEFILE)
  293.     {
  294.         /* get it */
  295.         if (debugbackup)
  296.             printf("BACKUP: Getting %s\n", currnode->pname) ;
  297.         /* build up the command to do the get */
  298.         strcpy (cmd, "get ") ;
  299.         strcat (cmd, currnode->pname) ;
  300.         /* its now safe to call the path munger as we have a copy of the
  301.            path in cmd */
  302.         backupbuildpath(currnode->pname, path, targetpath, psionpath) ;
  303.         strcat(cmd, " ") ;
  304.         strcat(cmd,targetpath) ;
  305.         if (debugbackup)
  306.             printf("BACKUP: doing %s\n",cmd) ;
  307.         /* if VAR_BACKUPNODO just print the command */
  308.         if (findvar(VAR_BACKUPNODO) != NULL)
  309.         {
  310.             printf("BACKUP: Would have done \"%s\"\n", cmd);
  311.         }
  312.         else
  313.         {
  314.             /* if VAR_BACKUPASK check to see if we went to do this one */
  315.             if (findvar(VAR_BACKUPASK) != NULL) 
  316.             {
  317.                 printf("BACKUP: Do you want to backup file %s ? (y/n) ", currnode->pname) ;
  318.                 fgets(resp, sizeof(resp), stdin) ;
  319.                 if ((resp[0] == 'y') || (resp[0] == 'Y'))
  320.                 {
  321.                     cmdintr(cmd) ;
  322.                 }
  323.             }
  324.             else
  325.             {
  326.                 cmdintr(cmd) ;
  327.             }
  328.         }
  329.         /* increment the filecount */
  330.         filecount ++ ;
  331.         return ;
  332.     }
  333.     else
  334.     {
  335.         /* the current entry is a directory, make it in the filesystem and then look at all its children */
  336.         /* make the directory */
  337.         if (debugbackup)
  338.             printf("BACKUP: Making dir %s\n",currnode->pname) ;
  339.         /* build up the command to do the mkdir */
  340.         strcpy (cmd, "mkdir -p  ") ;
  341.         backupbuildpath(currnode->pname, path, targetpath, psionpath) ;
  342.         strcat(cmd,targetpath) ;
  343.         if (debugbackup)
  344.             printf("BACKUP: doing system(%s)\n", cmd) ;
  345.         /* if VAR_BACKUPNODO just print the command */
  346.         if (findvar(VAR_BACKUPNODO) != NULL)
  347.         {
  348.             printf("BACKUP: Would have done \"%s\"\n", cmd);
  349.         }
  350.         else
  351.         {
  352.             /* if VAR_BACKUPASK check to see if we went to do this one */
  353.             if (findvar(VAR_BACKUPASK) != NULL) 
  354.             {
  355.                 printf("BACKUP: Do you want to backup directory %s ? (y/n) ", currnode->pname) ;
  356.                 fgets(resp, sizeof(resp), stdin) ;
  357.                 if ((resp[0] == 'y') || (resp[0] == 'Y'))
  358.                 {
  359.                     system(cmd) ;
  360.                 }
  361.                 else
  362.                 {
  363.                     printf("BACKUP: Warning, as you are not backing up directory %s none of its children will be backed up\n", currnode->pname) ;
  364.                     return ;
  365.                 }    
  366.             }
  367.             else
  368.             {
  369.                 system(cmd) ;
  370.             }
  371.         }
  372.         /* for each entry in the current get  the children */
  373.         child = currnode->children ;
  374.         while(child != NULL)
  375.         {
  376.             dobackup(path,child, psionpath) ;
  377.             child = child -> next ;
  378.         }
  379.         /* no children left increment the dircount and return */
  380.         dircount ++ ;
  381.         return ;
  382.     }
  383. }
  384.  
  385. backupbuildpath(path, root, target, purge)
  386. char * path, *root, *target, *purge;
  387. {
  388.     int i ;
  389.     char tmp[1024],*  tmpptr ;
  390.     if(debugcall >= BACKUPCALLDEBUG)
  391.         fprintf(stderr, "CALL backupbuildpath (path = %s, root = %s, target = OMITTED, purge = %s)\n", path, root, purge) ;
  392.     /* path is the path to munge (remove purge change all \ to /) */
  393.     /* also change all $ to S the drive is assumed to be the purge entry*/
  394.     /* root is the unix directory at the top of this tree */
  395.     /* target is the place to put the resultant string */
  396.  
  397.     strcpy(tmp, path) ;
  398.     tmpptr = tmp ;
  399.     /* whilst the two are the same and neither are the end of string move
  400.        allong the two removing characters from the front of the array */
  401.     while ((purge[0] == tmpptr[0]) && (purge[0] != '\0') && (tmpptr[0] != '\0'))
  402.     {
  403.         purge ++ ;
  404.         tmpptr ++ ;
  405.     }
  406.     
  407.     /* change the \ to / and $ to S */
  408.     for (i = 0 ; i < (int) strlen(tmpptr) ; i ++ )
  409.     {
  410.         if (tmpptr[i] == '$')
  411.         {
  412.             tmpptr[i] = 'S' ;
  413.         }
  414.         else if (tmpptr[i] == '\\') 
  415.         {
  416.             tmpptr[i] = '/' ;
  417.         }
  418.     }
  419.     /* build the output name */
  420.     strcpy(target, root) ;
  421.     strcat(target,tmpptr) ;
  422.     if(debugcall >= BACKUPCALLDEBUG)
  423.         fprintf(stderr, "EXIT: backupbuildpath (target = %s)\n", target) ;
  424. }
  425. long psgetmodtime() ;
  426. backupmodified(psname, backupdir, psionpath)
  427. char * psname,  *backupdir, *psionpath;
  428. {
  429.     char sunpath [1024] ;
  430.     char tmp [100] ;
  431.     long pstime , suntime ;
  432.     struct stat sunstat ;
  433.     int ret ;
  434.     if (debugcall >= BACKUPCALLDEBUG)
  435.         fprintf(stderr, "CALL: backupmodified (psname = %s, backupdir = %s, psionpath= %s)\n",psname, backupdir, psionpath) ;
  436.  
  437.     /* has the file on the psion been changes more recently 
  438.        than the backup ? */
  439.     
  440.     pssetpath(psname) ;
  441.     pstime = psgetmodtime() ;
  442.     
  443.     /* create a temporary copy of the psname so we can work on it */
  444.     strcpy(tmp, psname) ;
  445.     /* get the sunname for this */
  446.     backupbuildpath(tmp, backupdir, sunpath, psionpath) ;
  447.     
  448.     /* get the mod time of the sun file if it exists */
  449.     ret = stat(sunpath, &sunstat) ;
  450.     if (ret != 0)
  451.         return(FALSE) ;
  452.         
  453. #ifndef SVR4
  454.     if (debugbackup)
  455.         printf("ret = %d suntime = %ld pstime = %ld\n", ret, sunstat.st_mtime, pstime) ;
  456.     if ((pstime + CLOCKDIFF) < sunstat.st_mtime)
  457.         return(TRUE) ;
  458.     else
  459.         return(FALSE) ; 
  460. #else
  461.     if (debugbackup)
  462.         printf("ret = %d suntime = %ld pstime = %ld\n", ret, sunstat.st_mtim.tv_sec, pstime) ;
  463.  
  464.     if ((pstime + CLOCKDIFF) < sunstat.st_mtim.tv_sec)
  465.         return(TRUE) ;
  466.     else
  467.         return(FALSE) ; 
  468. #endif
  469. }
  470.  
  471. /* the restore code lives here */
  472. psrestore(psionpath,restoredir, incr)
  473. char * psionpath,* restoredir ;
  474. {
  475.     int filefilterwasset; 
  476.     int ch ;
  477.     time_t timestart, timeend ;
  478.     if (debugcall >= BACKUPCALLDEBUG)
  479.         fprintf(stderr, "CALL: psrestore (psionpath = %s, restoredir = %s, incr = %d)\n", psionpath, restoredir, incr) ;    
  480.         
  481.     /* if backupnocheck is set dont ask the user to close all the files
  482.        This is potentialy dangerous as suncom can't put a file if it is
  483.        open */
  484.     if (findvar(VAR_BACKUPNOCHECK) == NULL)
  485.     {
  486.         /* ask the user to ensure that all open files on the psion are closed */
  487.         printf("RESTORE: Please ensure that all files on the psion are closed\n");
  488.         printf("RESTORE: Press return to continue\n");
  489.         ch = getchar();
  490.     }
  491.     /* is this incremental ? */
  492.     incremental = incr ;
  493.     /* reset the file/dir counts */
  494.     filecount = 0 ;
  495.     dircount = 0 ;
  496.     /* get the start time */
  497.     timestart = time(NULL) ;
  498.     if (findvar(VAR_VERBOSE) != NULL)
  499.     {
  500.         printf("RESTORE: Starting %srestore of %s to %s\n", incremental ? "incremental " : "", restoredir, psionpath);
  501.         printf("RESTORE: %s\n", ctime(×tart)) ;
  502.         printf("RESTORE: Stage 1, Building file list\n");
  503.     }
  504.     /* NOTE we are using the same data structures for backup as restore */
  505.     initbackuplist(restoredir) ;
  506.     /* was VAR_FILEFILT set ? if so unsetit */
  507.     if (findvar(VAR_FILEFILT) != NULL)
  508.     {
  509.         filefilterwasset=TRUE ;
  510.         delvar(VAR_FILEFILT) ;
  511.     }
  512.     /* build a list of files to restore using the excludlist*/
  513.     restorelist(backhead,TRUE, psionpath, restoredir) ;
  514.     /* do the restore */
  515.     if (findvar(VAR_VERBOSE) != NULL)
  516.         printf("RESTORE: Stage 2, Putting files\n");
  517.     dorestore(psionpath,backhead, restoredir) ;
  518.     /* free the accumulated data structures */
  519.     closebackuplist(backhead) ;
  520.     /* reset the VAR_FILEFILT if it was set */
  521.     if (filefilterwasset)
  522.         addvar(VAR_FILEFILT,"")  ;
  523.     timeend = time(NULL) ;
  524.     if (findvar(VAR_VERBOSE) != NULL)
  525.     {
  526.         printf("RESTORE: %s of %s to %s complete\n", incremental ? "Incremental restore" : "Restore", restoredir, psionpath) ;
  527.         printf("RESTORE: %s\n", ctime(&timeend)) ;
  528.         printf("RESTORE: %d directories, %d files\n", dircount, filecount) ;
  529.         printf("RESTORE: Time taken %d seconds\n", (int) timeend - timestart) ;
  530.     }
  531.         
  532. }
  533. restorelist(currnode,exclude, psionpath, restoredir)
  534. struct backupentry *currnode ;
  535. int exclude ;
  536. char * psionpath, *restoredir ;
  537. {
  538.     int i ;
  539.     char tmp[100],  nodepath[1024], tmp1[1024];
  540.     FILE * fd ;
  541.     struct backupentry *child ;
  542.     int nodepathlen ;
  543.     if (debugcall >= BACKUPCALLDEBUG)
  544.         fprintf(stderr, "CALL: restorelist (currnode->pname = %s, exclude = %d, psionpath = %s, restoredir = %s)\n", currnode->pname, exclude, psionpath, restoredir) ;    
  545.     /* are we using the excludelist ? if so is thie item on it ? */
  546.     if (exclude)
  547.     {
  548.         if (currnode->exclude = findexclude(currnode->pname))
  549.             return ;
  550.     }
  551.     /* if the current node is a file set the flg and and check
  552.        that the file mod has not changed, if so exclude it */
  553.     if ((currnode->nodetype=restorepathtype(currnode->pname)) == BACKUPNODEFILE)
  554.     {
  555.         if (incremental)
  556.             currnode->exclude = restoremodified(currnode->pname,psionpath, restoredir) ;
  557.         return ;
  558.     }
  559.     /* check that it realy is a directory */
  560.     if (currnode->nodetype == BACKUPNODEUNKNOWN)
  561.         return ;
  562.     /* the current node is a directory, Lets work on it */
  563.     /* build up the list command */
  564.     sprintf(tmp, "ls %s > %s", currnode->pname, BACKUPLISTNAME) ;
  565.     /* list the current node use unix to do the work ! */
  566.     system(tmp) ;
  567.     /* we now have a list in BACKUPLISTNAME of all the items in this node lets get them !*/
  568.     if ((fd = fopen(BACKUPLISTNAME,"r")) == NULL)
  569.     {
  570.         printf("ERROR: Error in opening restore temporary file quiting\n") ;
  571.         psdc() ;
  572.     }
  573.     while (fgets(tmp1,120,fd) != NULL)
  574.     /* for each item in the current node */
  575.     {
  576.         /* as we use ls which does not give the entire pathname add
  577.            currnode->pname to the string */
  578.         sprintf(nodepath, "%s/%s", currnode->pname, tmp1) ;
  579.         /* if the last char is newline, removeit, cmdintr
  580.             doesnot like it */
  581.         nodepathlen = strlen(nodepath) ;
  582.         if (nodepath[nodepathlen -1] == '\n')
  583.             nodepath[nodepathlen -1] = 0 ;
  584.         if (debugbackup)
  585.             printf("Now working on %s\n", nodepath) ;
  586.         /* create a new node and install its name */
  587.         backupaddchild(currnode,nodepath) ;
  588.     }
  589.     fclose(fd) ;
  590.     /* remove the tmp file so others running the program won't 
  591.        have a problem */
  592.     if (unlink (BACKUPLISTNAME))
  593.         printf("ERROR: Error in removing restore temporary file\n") ;
  594.     /* get ready to scan the children in the current node */
  595.     child = currnode->children ;    
  596.     /* for each item in the current node */
  597.     while(child != NULL)
  598.     {
  599.         /* recursively call restorelist to work on the new item */
  600.         restorelist(child,exclude, psionpath, restoredir) ;
  601.         child = child->next ;
  602.     }
  603. }
  604. restorepathtype(path)
  605. char * path ;
  606. {
  607.     struct stat sunstat ;
  608.     int ret ;
  609.     if (debugcall >= BACKUPCALLDEBUG)
  610.         fprintf(stderr, "CALL: restorepathtype(path = %s)\n", path) ;
  611.     ret = stat(path, &sunstat) ;
  612.     if (S_ISDIR(sunstat.st_mode))
  613.     {
  614.         return(BACKUPNODEDIR) ;
  615.     }
  616.     else if (S_ISREG(sunstat.st_mode))
  617.     {
  618.         return(BACKUPNODEFILE);
  619.     }
  620.     else
  621.     {
  622.         return(BACKUPNODEUNKNOWN) ;
  623.     }
  624. }
  625.  
  626. dorestore(path,currnode, restoredir)
  627. char * path , *restoredir;
  628. struct backupentry * currnode ;
  629. {
  630.     int i ;
  631.     char * tmp ;
  632.     char targetpath [1024] ;
  633.     char cmd[2048] ;
  634.     char resp[10] ;
  635.     struct backupentry * child ;
  636.     if (debugcall >= BACKUPCALLDEBUG)
  637.         fprintf(stderr, "CALL: dorestore (path = %s, currnode->pname = %s, restoredir = %s)\n",path, currnode->pname, restoredir) ;
  638.     /* check that the current node is not excluded */
  639.     if (currnode->exclude)
  640.         return ;
  641.     /* if the type of the current node is unknown return */
  642.     if (currnode->nodetype == BACKUPNODEUNKNOWN)
  643.         return ;
  644.     /* if the current entry is a file get it and return */
  645.     if (currnode->nodetype == BACKUPNODEFILE)
  646.     {
  647.         /* get it */
  648.         if (debugbackup)
  649.             printf("RESTORE: Putting %s\n", currnode->pname) ;
  650.         /* build up the command to do the put */
  651.         restorebuildpath(currnode->pname, path, targetpath, restoredir) ;
  652.         sprintf(cmd, "put %s %s", targetpath, currnode->pname) ;
  653.         if (debugbackup)
  654.             printf("RESTORE: doing %s\n",cmd) ;
  655.         /* if VAR_BACKUPNODO just print the command */
  656.         if (findvar(VAR_BACKUPNODO) != NULL)
  657.         {
  658.             printf("RESTORE: Would have done \"%s\"\n", cmd);
  659.         }
  660.         else
  661.         {
  662.             /* if VAR_RESTOREASK check to see if we went to do this one */
  663.             if (findvar(VAR_RESTOREASK) != NULL) 
  664.             {
  665.                 printf("RESTORE: Do you want to restore file %s ? (y/n) ", currnode->pname) ;
  666.                 fgets(resp, sizeof(resp), stdin) ;
  667.                 if ((resp[0] == 'y') || (resp[0] == 'Y'))
  668.                 {
  669.                     cmdintr(cmd) ;
  670.                 }
  671.             }
  672.             else
  673.             {
  674.                 cmdintr(cmd) ;
  675.             }
  676.         }
  677.         /* increment the filecount */
  678.         filecount ++ ;
  679.         return ;
  680.     }
  681.     else
  682.     {
  683.         /* the current entry is a directory, make it in the filesystem and then look at all its children */
  684.         /* make the directory */
  685.         if (debugbackup)
  686.             printf("RESTORE: Making dir %s\n",currnode->pname) ;
  687.         /* build up the command to do the mkdir */
  688.         strcpy (cmd, "mkdir ") ;
  689.         restorebuildpath(currnode->pname, path, targetpath, restoredir) ;
  690.         strcat(cmd,targetpath) ;
  691.         if (debugbackup)
  692.             printf("RESTORE: doing cmdintr(%s)\n", cmd) ;
  693.         /* if VAR_BACKUPNODO just print the command */
  694.         if (findvar(VAR_BACKUPNODO) != NULL)
  695.         {
  696.             printf("RESTORE: Would have done \"%s\"\n", cmd) ;
  697.         }
  698.         else
  699.         {
  700.             /* if VAR_RESTOREASK check to see if we went to do this one */
  701.             if (findvar(VAR_RESTOREASK) != NULL) 
  702.             {
  703.                 printf("RESTORE: Do you want to restore directory %s ? (y/n) ", currnode->pname) ;
  704.                 fgets(resp, sizeof(resp), stdin) ;
  705.                 if ((resp[0] == 'y') || (resp[0] == 'Y'))
  706.                 {
  707.                     cmdintr(cmd) ;
  708.                 }
  709.                 else
  710.                 {
  711.                     printf("RESTORE: Warning, as you are not restoring up directory %s none of its children will be backed up\n", currnode->pname) ;
  712.                     return ;
  713.                 }    
  714.             }
  715.             else
  716.             {
  717.                 cmdintr(cmd) ;
  718.             }
  719.         }
  720.         /* for each entry in the current get  the children */
  721.         child = currnode->children ;
  722.         while(child != NULL)
  723.         {
  724.             dorestore(path,child, restoredir) ;
  725.             child = child -> next ;
  726.         }
  727.         /* no children left increment the dircount and return */
  728.         dircount ++ ;
  729.         return ;
  730.     }
  731. }
  732.  
  733. restorebuildpath(path, root, target,purge)
  734. char * path, *root, *target, *purge ;
  735. {
  736.     int i ;
  737.     char tmp[1024], *tmpptr;
  738.     /* path is the path to munge (add root drive:, change all / to \) */
  739.     /* also change all S to $, if purge exists at the front of the path*/
  740.     /* remove those characters if they match*/
  741.     /* root is the psion directory at the top of this tree (e.g. m:) */
  742.     /* target is the place to put the resultant string */
  743.     if (debugcall >= BACKUPCALLDEBUG)
  744.         fprintf(stderr, "CALL: restorebuildpath (path = %s, root = %s target = OMITTED, purge = %s )\n",path, root, purge) ;
  745.  
  746.     strcpy(tmp, path) ;
  747.     tmpptr = tmp ;
  748.     /* whilst the two are the same and neither are the end of string move
  749.        allong the two removing characters from the front of the array */
  750.     while ((purge[0] == tmpptr[0]) && (purge[0] != '\0') && (tmpptr[0] != '\0'))
  751.     {
  752.         purge ++ ;
  753.         tmpptr ++ ;
  754.     }
  755.     /* change the / to \ and S to $ */
  756.     for (i = 0 ; i < (int) strlen(tmpptr) ; i ++ )
  757.     {
  758.         if (tmpptr[i] == 'S')
  759.         {
  760.             tmpptr[i] = '$' ;
  761.         }
  762.         else if (tmpptr[i] == '/') 
  763.         {
  764.             tmpptr[i] = '\\' ;
  765.         }
  766.     }
  767.     /* build the output name */
  768.     strcpy(target, root) ;
  769.     strcat(target,tmpptr) ;
  770.     if (debugcall >= BACKUPCALLDEBUG)
  771.         fprintf(stderr, "EXIT: restorebuildpath (target = %s)\n", target) ;
  772. }
  773. restoremodified(sunname, psiondir, restdir)
  774. char * sunname,  *psiondir , *restdir;
  775. {
  776.     char psionpath [1024] ;
  777.     char tmp [1000] ;
  778.     long pstime , suntime ;
  779.     struct stat sunstat ;
  780.     int ret ;
  781.     if (debugcall >= BACKUPCALLDEBUG)
  782.         fprintf(stderr, "CALL: restoremodified (sunname = %s, psiondir = %s, restdir = %s )\n",sunname, psiondir, restdir) ;
  783.  
  784.     /* has the file on the psion been changes more recently 
  785.        than the one on the sun ? if so return FALSE else TRUE*/
  786.     
  787.  
  788.     /* create a temporary copy of the sunname so we can work on it */
  789.     strcpy(tmp, sunname) ;
  790.     /* get the psionname for this */
  791.     restorebuildpath(tmp, psiondir, psionpath, restdir) ;
  792.     pssetpath(psionpath) ;
  793.     /* does the psion file exist ? if so get the time else FALSE */
  794.     if (psep())
  795.         pstime = psgetmodtime() ;
  796.     else
  797.         return(FALSE) ;    
  798.     ret = stat(sunname, &sunstat) ;
  799.  
  800.         
  801. #ifndef SVR4
  802.     if (debugbackup)
  803.         printf("ret = %d suntime = %ld pstime = %ld\n", ret, sunstat.st_mtime, pstime) ;
  804.     if (pstime  > (sunstat.st_mtime + CLOCKDIFF))
  805.         return(TRUE) ;
  806.     else
  807.         return(FALSE) ; 
  808. #else
  809.     if (debugbackup)
  810.         printf("ret = %d suntime = %ld pstime = %ld\n", ret, sunstat.st_mtim.tv_sec, pstime) ;
  811.  
  812.     if (pstime  > (sunstat.st_mtim.tv_sec + CLOCKDIFF))
  813.         return(TRUE) ;
  814.     else
  815.         return(FALSE) ; 
  816. #endif
  817. }
  818.