home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / rolodex / part2 / rolo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  8.5 KB  |  366 lines

  1. #include <sys/file.h>
  2. #include <stdio.h>
  3. #include <ctype.h>
  4. #include <sgtty.h>
  5. #include <signal.h>
  6. #include <curses.h>
  7. #include <pwd.h>
  8.  
  9. #include "sys5.h"
  10.  
  11. #ifdef TMC
  12. #include <ctools.h>
  13. #else
  14. #include "ctools.h"
  15. #endif
  16. #include "args.h"
  17. #include "menu.h"
  18. #include "mem.h"
  19.  
  20. #include "rolofiles.h"
  21. #include "rolodefs.h"
  22. #include "datadef.h"
  23.  
  24.  
  25. static char rolodir[DIRPATHLEN];        /* directory where rolo data is */
  26. static char filebuf[DIRPATHLEN];        /* stores result of homedir() */
  27.  
  28. int changed = 0;
  29. int reorder_file = 0;
  30. int rololocked = 0;
  31. int in_search_mode = 0;
  32.  
  33.  
  34. char *rolo_emalloc (size) int size;
  35.  
  36. /* error handling memory allocator */
  37.  
  38. {
  39.   char *rval;        
  40.   if (0 == (rval = malloc(size))) {        
  41.      fprintf(stderr,"Fatal error:  out of memory\n");
  42.      save_and_exit(-1);
  43.   }
  44.   return(rval);
  45. }  
  46.  
  47.         
  48. char *copystr (s) char *s;
  49.  
  50. /* memory allocating string copy routine */
  51.  
  52.  
  53. {
  54.  char *copy;        
  55.  if (s == 0) return(0);
  56.  copy = rolo_emalloc(strlen(s) + 1);
  57.  strcpy(copy,s);
  58.  return(copy);
  59. }
  60.  
  61.  
  62. char *timestring ()
  63.  
  64. /* returns a string timestamp */
  65.  
  66. {
  67.   char *s;        
  68.   long timeval;
  69.   time(&timeval);
  70.   s = ctime(&timeval);  
  71.   s[strlen(s) - 1] = '\0';
  72.   return(copystr(s));
  73. }  
  74.   
  75.  
  76. user_interrupt ()
  77.  
  78. /* if the user hits C-C (we assume he does it deliberately) */
  79.  
  80. {
  81.   unlink(homedir(ROLOLOCK));
  82.   fprintf(stderr,"\nAborting rolodex, no changes since last save recorded\n");
  83.   exit(-1);  
  84. }  
  85.  
  86.  
  87. user_eof ()
  88.  
  89. /* if the user hits C-D */
  90.  
  91. {
  92.   unlink(homedir(ROLOLOCK));        
  93.   fprintf(stderr,"\nUnexpected EOF on terminal. Saving rolodex and exiting\n");
  94.   save_and_exit(-1);        
  95. }
  96.  
  97.  
  98. roloexit (rval) int rval;
  99. {
  100.   if (rololocked) unlink(homedir(ROLOLOCK));        
  101.   exit(rval);
  102. }  
  103.  
  104.  
  105. save_to_disk ()
  106.  
  107. /* move the old rolodex to a backup, and write out the new rolodex and */
  108. /* a copy of the new rolodex (just for safety) */
  109.  
  110. {
  111.   FILE *tempfp,*copyfp;        
  112.   char d1[DIRPATHLEN], d2[DIRPATHLEN];
  113.   int r;
  114.         
  115.   tempfp = fopen(homedir(ROLOTEMP),"w");
  116.   copyfp = fopen(homedir(ROLOCOPY),"w");
  117.   if (tempfp == NULL || copyfp == NULL) {
  118.      fprintf(stderr,"Unable to write rolodex...\n");
  119.      fprintf(stderr,"Any changes made have not been recorded\n");
  120.      roloexit(-1);
  121.   }
  122.   write_rolo(tempfp,copyfp);
  123.   fclose(tempfp);
  124.   fclose(copyfp);
  125.   if (rename(strcpy(d1,homedir(ROLODATA)),strcpy(d2,homedir(ROLOBAK))) ||
  126.       rename(strcpy(d1,homedir(ROLOTEMP)),strcpy(d2,homedir(ROLODATA)))) {
  127.      fprintf(stderr,"Rename failed.  Revised rolodex is in %s\n",ROLOCOPY);
  128.      roloexit(-1);
  129.   }
  130.   printf("Rolodex saved\n");
  131.   sleep(1);
  132.   changed = 0;
  133. }
  134.   
  135.  
  136. save_and_exit (rval) int rval;
  137. {
  138.   if (changed) save_to_disk();        
  139.   roloexit(rval);        
  140. }
  141.  
  142.  
  143. extern struct passwd *getpwnam();
  144.  
  145. char *home_directory (name) char *name;
  146. {
  147.   struct passwd *pwentry;
  148.   if (0 == (pwentry = getpwnam(name))) return("");
  149.   return(pwentry -> pw_dir);
  150. }        
  151.  
  152.  
  153. char *homedir (filename) char *filename;
  154.  
  155. /* e.g., given "rolodex.dat", create "/u/massar/rolodex.dat" */
  156. /* rolodir generally the user's home directory but could be someone else's */
  157. /* home directory if the -u option is used. */
  158.  
  159. {
  160.   nbuffconcat(filebuf,3,rolodir,"/",filename);
  161.   return(filebuf);
  162. }
  163.  
  164.  
  165. char *libdir (filename) char *filename;
  166.  
  167. /* return a full pathname into the rolodex library directory */
  168. /* the string must be copied if it is to be saved! */
  169.  
  170. {
  171.   nbuffconcat(filebuf,3,ROLOLIB,"/",filename);        
  172.   return(filebuf);        
  173. }
  174.  
  175.  
  176. rolo_only_to_read () 
  177. {
  178.   return(option_present(SUMMARYFLAG) || n_non_option_args() > 0);
  179. }
  180.  
  181.  
  182. locked_action () 
  183. {
  184.   if (option_present(OTHERUSERFLAG)) {        
  185.      fprintf(stderr,"Someone else is modifying that rolodex, sorry\n");
  186.      exit(-1);
  187.   }
  188.   else {
  189.      cathelpfile(libdir("lockinfo"),"locked rolodex",0);
  190.      exit(-1);
  191.   }
  192. }  
  193.   
  194.  
  195. main (argc,argv) int argc; char *argv[];
  196.  
  197. {
  198.     int fd,in_use,read_only,rolofd;
  199.     Bool not_own_rolodex;        
  200.     char *user;
  201.     FILE *tempfp;
  202.     
  203.     clearinit();
  204.     clear_the_screen();
  205.     
  206.     /* parse the options and arguments, if any */
  207.     
  208.     switch (get_args(argc,argv,T,T)) {
  209.         case ARG_ERROR : 
  210.           roloexit(-1);
  211.         case NO_ARGS :
  212.           break;
  213.         case ARGS_PRESENT :
  214.           if (ALL_LEGAL != legal_options(LEGAL_OPTIONS)) {
  215.                 fprintf(stderr,"illegal option\nusage: %s\n",USAGE);
  216.                 roloexit(-1);
  217.           }
  218.     }
  219.     
  220.     /* find the directory in which the rolodex file we want to use is */
  221.     
  222.     not_own_rolodex = option_present(OTHERUSERFLAG);        
  223.     if (not_own_rolodex) {
  224.        if (NIL == (user = option_arg(OTHERUSERFLAG,1)) || 
  225.            n_option_args(OTHERUSERFLAG) != 1) {
  226.           fprintf(stderr,"Illegal syntax using -u option\nusage: %s\n",USAGE);
  227.           roloexit(-1);
  228.        }
  229.     }        
  230.     else {
  231.        if (0 == (user = getenv("HOME"))) {
  232.           fprintf(stderr,"Cant find your home directory, no HOME\n");
  233.           roloexit(-1);
  234.        }
  235.     }
  236.     
  237.     if (not_own_rolodex) {
  238.        strcpy(rolodir,home_directory(user));
  239.        if (*rolodir == '\0') {
  240.           fprintf(stderr,"No user %s is known to the system\n",user);
  241.           roloexit(-1);
  242.        }
  243.     }
  244.     else strcpy(rolodir,user);
  245.     
  246.     /* is the rolodex readable? */
  247.     
  248.     if (0 != access(homedir(ROLODATA),R_OK)) {
  249.         
  250.        /* No.  if it exists and we cant read it, that's an error */
  251.         
  252.        if (0 == access(homedir(ROLODATA),F_OK)) { 
  253.           fprintf(stderr,"Cant access rolodex data file to read\n");
  254.           roloexit(-1);
  255.        }
  256.        
  257.        /* if it doesn't exist, should we create one? */
  258.        
  259.        if (option_present(OTHERUSERFLAG)) {
  260.           fprintf(stderr,"No rolodex file belonging to %s found\n",user);
  261.           roloexit(-1);
  262.        }
  263.        
  264.        /* try to create it */
  265.        
  266.        if (-1 == (fd = creat(homedir(ROLODATA),0644))) {
  267.           fprintf(stderr,"couldnt create rolodex in your home directory\n");
  268.           roloexit(-1);
  269.        }
  270.        
  271.        else {
  272.           close(fd);
  273.           fprintf(stderr,"Creating empty rolodex...\n");
  274.        }
  275.  
  276.     }
  277.     
  278.     /* see if someone else is using it */
  279.     
  280.     in_use = (0 == access(homedir(ROLOLOCK),F_OK));
  281.     
  282.     /* are we going to access the rolodex only for reading? */
  283.     
  284.     if (!(read_only = rolo_only_to_read())) {
  285.     
  286.        /* No.  Make sure no one else has it locked. */
  287.         
  288.        if (in_use) {
  289.           locked_action();
  290.        }
  291.         
  292.        /* create a lock file.  Catch interrupts so that we can remove */
  293.        /* the lock file if the user decides to abort */
  294.        
  295.        if (!option_present(NOLOCKFLAG)) {
  296.           if ((fd = open(homedir(ROLOLOCK),O_EXCL|O_CREAT,00200|00400)) < 0) {
  297.              fprintf(stderr,"unable to create lock file...\n");
  298.          exit(1);
  299.       }
  300.           rololocked = 1;
  301.           close(fd);
  302.           signal(SIGINT,user_interrupt);        
  303.        }
  304.         
  305.        /* open a temporary file for writing changes to make sure we can */
  306.        /* write into the directory */
  307.        
  308.        /* when the rolodex is saved, the old rolodex is moved to */
  309.        /* a '~' file, the temporary is made to be the new rolodex, */
  310.        /* and a copy of the new rolodex is made */
  311.        
  312.        if (NULL == (tempfp = fopen(homedir(ROLOTEMP),"w"))) {
  313.            fprintf(stderr,"Can't open temporary file to write to\n");
  314.            roloexit(-1);
  315.        }        
  316.        fclose(tempfp);
  317.     
  318.     }
  319.        
  320.     allocate_memory_chunk(CHUNKSIZE);
  321.     
  322.     if (NULL == (rolofd = open(homedir(ROLODATA),O_RDONLY))) {
  323.         fprintf(stderr,"Can't open rolodex data file to read\n");
  324.         roloexit(-1);
  325.     }
  326.     
  327.     /* read in the rolodex from disk */
  328.     /* It should never be out of order since it is written to disk ordered */
  329.     /* but just in case... */
  330.     
  331.     if (!read_only) printf("Reading in rolodex from %s\n",homedir(ROLODATA));
  332.     read_rolodex(rolofd);
  333.     close(rolofd);
  334.     if (!read_only) printf("%d entries listed\n",rlength(Begin_Rlist));
  335.     if (reorder_file && !read_only) {
  336.        fprintf(stderr,"Reordering rolodex...\n");
  337.        rolo_reorder();
  338.        fprintf(stderr,"Saving reordered rolodex to disk...\n");
  339.        save_to_disk();
  340.     }
  341.        
  342.     /* the following routines live in 'options.c' */
  343.     
  344.     /* -s option.  Prints a short listing of people and phone numbers to */
  345.     /* standard output */
  346.     
  347.     if (option_present(SUMMARYFLAG)) {
  348.         print_short();
  349.         exit(0);
  350.     }
  351.     
  352.     /* rolo <name1> <name2> ... */
  353.     /* print out info about people whose names contain any of the arguments */
  354.     
  355.     if (n_non_option_args() > 0) {
  356.        print_people();
  357.        exit(0);
  358.     }
  359.     
  360.     /* regular rolodex program */
  361.     
  362.     interactive_rolo();
  363.     exit(0);
  364.     
  365. }    
  366.