home *** CD-ROM | disk | FTP | other *** search
/ Internet Publisher's Toolbox 1.0 / Image.iso / toolbox / ntserver / wtsource / futil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-15  |  18.6 KB  |  786 lines

  1. /* Wide AREA INFORMATION SERVER SOFTWARE    
  2.    No guarantees or restrictions.  See the readme file for the full standard
  3.    disclaimer.  
  4.   
  5.    3/90 Brewster
  6. */
  7.  
  8. /* Copyright (c) CNIDR (see ../COPYRIGHT) */
  9.  
  10.  
  11. /* Change log:
  12.  * $Log:    futil.c,v $
  13.  * Revision 1.2  93/07/01  19:18:02  warnock
  14.  * gethostname -> mygethostname
  15.  * 
  16.  * Revision 1.1  1993/02/16  15:05:35  freewais
  17.  * Initial revision
  18.  *
  19.  * Revision 1.21  92/03/24  10:30:41  jonathan
  20.  * Added fix to pathname_directory if no directory part, it puts "./" in the
  21.  * destination.
  22.  * 
  23.  * Revision 1.20  92/02/21  11:05:48  jonathan
  24.  * added RCSIdent
  25.  * 
  26.  * Revision 1.19  92/02/20  14:51:19  jonathan
  27.  * changed include for access() to sys/file.h, since that seems more portable.
  28.  * 
  29.  * Revision 1.18  92/02/18  11:52:43  jonathan
  30.  * conditionalized inclusion of unistd.h for NeXT (use fcntl instead).  This
  31.  * may be a BSD thing.
  32.  * 
  33.  * Revision 1.17  92/02/12  13:19:27  jonathan
  34.  * Added "$Log" so RCS will put the log message in the header
  35.  * 
  36.  
  37. */
  38.  
  39. #ifndef lint
  40. static char *RCSid = "$Header: /archives/stelar/src/freeWAIS/freeWAIS-0.2/ir/RCS/futil.c,v 1.2 93/07/01 19:18:02 warnock Exp $";
  41. #endif
  42.  
  43. /* ======================== */
  44. /* ===  File Utilities  === */
  45. /* ======================== */
  46.  
  47. #include <string.h>
  48.  
  49. #ifdef THINK_C
  50.   /* file type info */
  51. #include <pascal.h>     /* for CtoPstr */
  52. #include <FileMgr.h>
  53. #define CREATOR         'WIS1'
  54. #define WAIS_INDEX_FILE_TYPE    'INDX'
  55.  
  56. #else
  57.  
  58. #include <sys/types.h> /* for stat and getuid */
  59. #include <sys/stat.h> /* for stat */
  60. #ifdef WIN32
  61. #include <io.h> /* for _access() */
  62. #else
  63. #include <sys/param.h> /* for getwd */
  64. #include <sys/file.h> /* for access() */
  65. #endif /* WIN32 */
  66.  
  67. #endif /* THINK_C */
  68.  
  69. #ifdef LINUX
  70. #include <unistd.h>   /* to get R_OK IO flag */
  71. #endif
  72.  
  73. #include "futil.h"
  74. #include "panic.h"
  75.  
  76. #ifndef WIN32
  77. #ifndef R_OK
  78. #include <unistd.h>
  79. #endif
  80. #endif /* WIN32 */
  81. /*----------------------------------------------------------------------*/
  82.  
  83. static long numFilesCurrentlyOpen = 0;
  84. static long maxNumFilesOpenAtOneTime = 0;
  85.  
  86. FILE*
  87. fs_fopen(fileName,mode)
  88. char* fileName;
  89. char* mode;
  90. {
  91.   FILE* file = NULL;
  92.   
  93. #ifdef BSD
  94. #define implicitBinary
  95. #endif /* def BSD */
  96. #ifdef ultrix
  97. #define implicitBinary
  98. #endif /* def ultrix */
  99. #ifndef ANSI_LIKE
  100. #define implicitBinary
  101. #endif /* def ANSI_LIKE */
  102.  
  103.  
  104.  
  105. #ifdef implicitBinary
  106.    /* these old os's don't handle the binary mode.  Just remove it */
  107.    char realMode[100];
  108.    long i,j;
  109.    for (i = 0L,j = 0; mode[i] != '\0';i++)
  110.     { if (mode[i] != 'b')
  111.     realMode[j++] = mode[i];
  112.     }
  113.    realMode[j] = '\0';
  114.   file = fopen(fileName,realMode);
  115. #else
  116.   file = fopen(fileName,mode);
  117. #endif /* def implicitBinary */
  118.   
  119.   if (file != NULL)
  120.     { numFilesCurrentlyOpen++;
  121.       if (numFilesCurrentlyOpen > maxNumFilesOpenAtOneTime)
  122.     maxNumFilesOpenAtOneTime = numFilesCurrentlyOpen;
  123.     }
  124.   
  125.   return(file);
  126. }
  127.  
  128. /*----------------------------------------------------------------------*/
  129.  
  130. long
  131. fs_fclose(file)
  132. FILE* file;
  133.  
  134. {
  135.   if (file != NULL)
  136.     { numFilesCurrentlyOpen--;
  137.       return(fclose(file));
  138.     }
  139.   else
  140.     return(0L);
  141. }
  142.  
  143. /*----------------------------------------------------------------------*/
  144.  
  145. long fs_fseek(file,offset,wherefrom)
  146. FILE* file;
  147. long offset;
  148. long wherefrom;
  149. {
  150.   long result;
  151.   
  152.   if(NULL == file)
  153.     return -1;
  154.   
  155.   result = fseek(file, offset, wherefrom);
  156.  
  157.   /*
  158.   if(0 != result) 
  159.     panic("A seek failed:  offset %ld, wherefrom %d.\n",offset, wherefrom);
  160.     */
  161.   return result;
  162. }
  163.  
  164. /*----------------------------------------------------------------------*/
  165.  
  166. long fs_ftell(file)
  167. FILE* file;
  168. {
  169.   long result;
  170.   
  171.   if (file == NULL)
  172.     return(0);
  173.     
  174.   result = ftell(file);
  175.   
  176.   if(EOF == result)
  177.     panic("A seek on an index file failed.\n");
  178.  
  179.   return(result);
  180. }
  181.  
  182. /*----------------------------------------------------------------------*/
  183.  
  184. void grow_file(file,length)
  185. FILE* file;
  186. long length;
  187. {
  188.   long current_length;
  189.   s_fseek(file, 0L, SEEK_END);
  190.   current_length = s_ftell(file);
  191.   s_fseek(file, length - current_length, SEEK_END);
  192. }
  193.  
  194. /*----------------------------------------------------------------------*/
  195.  
  196. /* writes the high byte first, this makes reading faster */
  197. long write_bytes(value,size,stream)
  198. long value;
  199. long size;
  200. FILE* stream;
  201. {
  202.   long i;
  203.   long answer;
  204.   if((size < sizeof(long)) && (0 != (value >> (size * 8))))
  205.     panic("In a call to write_bytes, the value %ld can not be represented in %ld bytes", value, size);
  206.   for(i = size - 1; i >= 0; i--){
  207.     answer = putc((value >> (i * 8)) & 0xFF, stream);
  208.   }
  209.   if(ferror(stream) != 0) {
  210.     panic("Write failed");
  211.   }
  212.   return(answer);
  213. }
  214.  
  215. /*----------------------------------------------------------------------*/
  216.  
  217. /* returns EOF if it gets an error */
  218. long read_bytes(n_bytes,stream)
  219. long n_bytes;
  220. FILE *stream;
  221. {
  222.   long answer = 0;
  223.   unsigned long ch;
  224.   long i;
  225.   for(i = 0; i < n_bytes; i++){
  226.     ch = fgetc(stream);
  227.     if(EOF == ch){
  228.       return(EOF);
  229.     }
  230.     answer = (answer << 8) + (unsigned char)ch;
  231.   }
  232.   return(answer);
  233. }
  234.  
  235. /*----------------------------------------------------------------------*/
  236.  
  237. long read_bytes_from_memory(n_bytes,block)
  238. long n_bytes;
  239. unsigned char *block;
  240. {
  241.   long answer = 0;
  242.   unsigned char ch;
  243.   long i;
  244.   for(i = 0; i < n_bytes; i++){
  245.     ch = *(block++);
  246.     answer = (answer << 8) + ch;
  247.   }
  248.   return(answer);
  249. }
  250.  
  251. /*----------------------------------------------------------------------*/
  252.  
  253. time_t file_write_date(filename)
  254. char* filename;
  255. { /* os dependent */
  256. #ifdef THINK_C
  257.     return((time_t)0);  /* not implemented yet */
  258. #else
  259.   struct stat *buf = (struct stat*)s_malloc((size_t)sizeof(struct stat));
  260.   time_t mtime;
  261.  
  262.  
  263.  
  264.    if(0 != stat(filename, buf)) {
  265.      /* might be the compressed one. */
  266.      char buffer[MAX_FILENAME_LEN+2];
  267.      sprintf(buffer, "%s.Z", filename);
  268.      if (0 != stat(buffer, buf)) {
  269.        panic("could not stat %s", filename);
  270.      }
  271.   }
  272.  
  273.  
  274.   mtime =  buf->st_mtime;
  275.   s_free(buf);
  276.   return(mtime);
  277. #endif /* THINK_C */
  278. }
  279.  
  280. /*----------------------------------------------------------------------*/
  281.  
  282. long file_length(stream)
  283. FILE* stream;
  284. /* return the length (in bytes) of a stream - leave the current
  285.    position where it was
  286.  */ 
  287. {
  288.   long position = ftell(stream);
  289.   long end = -1;
  290.   s_fseek(stream, 0L, SEEK_END);
  291.   end = ftell(stream);  
  292.   s_fseek(stream,position,SEEK_SET);
  293.   return(end);
  294. }
  295.  
  296. /*----------------------------------------------------------------------*/
  297.  
  298. static char *clean_path _AP((char* filename));
  299.  
  300. static char *clean_path(filename)
  301. char *filename;
  302. /* this takes out the '/../' and the '/./' from the path by modifying 
  303.    the argument and returning it. The pathname passed to it must be a 
  304.    full path. This is not optimized. */
  305. {
  306. #ifndef THINK_C
  307. #ifndef WIN32
  308.   char *beginning_ptr = strstr(filename, "/../");
  309.   if(NULL != beginning_ptr){
  310.     /* then we have something to process.
  311.        reverse search for the beginning of the last directory,
  312.        in order to snuff it */
  313.     char *ptr;
  314.     for(ptr = beginning_ptr - 1; ptr >= filename; ptr--){
  315.       if(*ptr == '/'){
  316.     /* then we found the beginning of the path */
  317.     strcpy(ptr, beginning_ptr + strlen("/../") -1);
  318.     clean_path(filename);   /* get the other occurances of /../ */
  319.     break;
  320.       } 
  321.     }
  322.   }
  323.   /* now look for /./ */
  324.   beginning_ptr = strstr(filename, "/./");
  325.   if(NULL != beginning_ptr){
  326.     strcpy(beginning_ptr, beginning_ptr + strlen("/./") -1);
  327.     clean_path(filename);   /* get the other occurances of /./ */
  328.   }
  329. #endif /* ndef WIN32 */
  330. #endif              /* ndef THINK_C */
  331.  
  332.   return(filename);
  333.  
  334. }
  335.  
  336. /*----------------------------------------------------------------------*/
  337.     
  338. char *truename(filename,full_path)
  339. char *filename;
  340. char *full_path;
  341. {
  342.   /* this puts into full_path the full pathname including directory.
  343.    */
  344. #if defined(THINK_C) || defined(WIN32)
  345.   strcpy(full_path, filename);
  346.   return(full_path); /* do nothing */
  347. #else
  348.   if('/' == filename[0]){
  349.     /* then it is complete already */
  350.     strcpy(full_path, filename);
  351.     clean_path(full_path);
  352.     return(full_path);
  353.   }
  354.   else{
  355.     getcwd(full_path,1024);
  356.     s_strncat(full_path,"/",MAX_FILENAME_LEN,MAX_FILENAME_LEN);
  357.     s_strncat(full_path,filename,MAX_FILENAME_LEN,MAX_FILENAME_LEN);
  358.     clean_path(full_path);
  359.     return(full_path);
  360.   }
  361. #endif /* THINK_C */
  362. }
  363.  
  364. /*----------------------------------------------------------------------*/
  365.  
  366. char *pathname_name(pathname)
  367. char *pathname;
  368. /* returns a pointer to the leaf name part of full pathname.
  369.    equivalent to common lisp pathname-name. */
  370. {
  371. #ifdef WIN32
  372.   char *answer = strrchr(pathname, '\\');
  373. #else
  374. #ifdef THINK_C
  375.   char *answer = strrchr(pathname, ':');
  376. #else
  377.   char *answer = strrchr(pathname, '/');
  378. #endif  /* THINK_C */
  379. #endif  /* WIN32 */
  380.  
  381.   if(NULL == answer)
  382.     return(pathname);
  383.   return(answer + 1);
  384. }
  385.  
  386. /*----------------------------------------------------------------------*/
  387.  
  388. char *pathname_directory(pathname,destination)
  389. char *pathname;
  390. char *destination;
  391. /* returns a pointer to a string of the directory part of
  392.    the pathname and modifies its destination argument.
  393.    This is the equivalent to the common lisp pathname-directory function. */
  394. {
  395. #ifdef WIN32
  396.   char *dirptr = strrchr(pathname, '\\');
  397. #else
  398. #ifdef THINK_C
  399.   char *dirptr = strrchr(pathname, ':');
  400. #else
  401.   char *dirptr = strrchr(pathname, '/');
  402. #endif /* THINK_C */
  403. #endif /* WIN32 */
  404.  
  405.   if(NULL == dirptr)
  406. #ifdef WIN32
  407.     strncpy(destination, ".\\", MAX_FILENAME_LEN);
  408. #else
  409. #ifdef THINK_C
  410.     strncpy(destination, pathname, MAX_FILE_NAME_LEN);
  411. #else
  412.     strncpy(destination, "./", MAX_FILENAME_LEN);
  413. #endif /* THINK_C */
  414. #endif /* WIN32 */
  415.   else
  416.     { strncpy(destination, pathname, MAX_FILE_NAME_LEN);
  417.       destination[dirptr - pathname + 1] = '\0';
  418.     }
  419.  
  420.   return(destination);
  421. }
  422.   
  423. /*----------------------------------------------------------------------*/
  424.  
  425. /* Setting the Macintosh File type (requires the MacTraps library) */
  426. /* from Util.c by Harry Morris */
  427.  
  428. #ifdef THINK_C
  429.  
  430. void 
  431. setFileType(fileName,type,creator)
  432. char* fileName;
  433. FType type;
  434. FType creator;
  435.   FInfo info;
  436.   OSErr error;
  437.   
  438.   CtoPstr(fileName);
  439.   error = GetFInfo((StringPtr)fileName,0L,&info);
  440.   if (error != noErr)
  441.     panic("error - Can't get file type of file %s, code %ld\n",
  442.           PtoCstr((char*)fileName),noErr);
  443.   info.fdType = type;
  444.   info.fdCreator = creator;
  445.   error = SetFInfo((StringPtr)fileName,0L,&info);
  446.   if (error != noErr)
  447.     panic("error - Can't change file type of file %s, code %ld\n",
  448.           PtoCstr((char*)fileName),noErr);
  449.   PtoCstr((char*)fileName);
  450. }
  451.  
  452. #endif /* THINK_C */
  453.  
  454. /*----------------------------------------------------------------------*/
  455.  
  456. char *current_user_name()
  457. /* returns the current_user_name as a mail address */
  458. {
  459.   static char answer[200];
  460. #ifndef WIN32  
  461.   char hostname[120];
  462. #endif
  463.   
  464. #ifdef THINK_C
  465.   strcpy(answer,"MAC"); /* could look up the name in the chooser */
  466. #endif /* def THINK_C */
  467.  
  468. #ifdef M_XENIX
  469.   strcpy(answer,"unknown"); /* could look up the name in the chooser */
  470. #endif /* def M_XENIX */
  471.  
  472. #ifdef WIN32
  473.   strcpy(answer,"unknown"); /* Could get it from the GetUserName function */
  474. #endif /* WIN32 */
  475.  
  476. #ifndef THINK_C
  477. #ifndef M_XENIX
  478. #ifndef WIN32
  479.  
  480. #include <pwd.h>  /* for getpwent */
  481.  
  482.   struct passwd *pwent = getpwuid(getuid());
  483.   strncpy(answer, pwent->pw_name, 200);
  484.   strncat(answer, "@", 200);
  485.   mygethostname(hostname, 120);
  486.   strncat(answer, hostname, 200);
  487.  
  488. #endif /* ndef WIN32 */
  489. #endif /* ndef M_XENIX */
  490. #endif /* ndef THINK_C */
  491.  
  492.   return(answer);
  493. }
  494.  
  495. /*----------------------------------------------------------------------*/
  496.  
  497. boolean probe_file(filename)
  498. char *filename;
  499. /* return true if it is there, false otherwise.
  500.    Can this be done faster? 
  501. */
  502. {
  503.   if (filename == NULL)
  504.     return(false);
  505. #ifdef WIN32
  506.   else if (_access(filename,4) == 0)
  507.     return(true);
  508. #else
  509.   else if (access(filename,R_OK) == 0)
  510.     return(true);
  511. #endif
  512.   else
  513.     return(false);
  514. }
  515.  
  516. /*----------------------------------------------------------------------*/
  517.  
  518. boolean probe_file_possibly_compressed(filename)
  519. char *filename;
  520. /* return true if it is there, false otherwise.
  521.    Can this be done faster? */
  522. {
  523.   if (filename == NULL)
  524.     return(false);
  525.   else if (!probe_file(filename))
  526.     { /* try the compression */
  527.       char buffer[ MAX_FILENAME_LEN * 2 ];
  528.       strcpy(buffer, filename);
  529.       strcat(buffer, ".Z");
  530.       return(probe_file(buffer));
  531.     }
  532.   else
  533.     return(true);
  534. }
  535.  
  536. /*----------------------------------------------------------------------*/
  537.  
  538. /* this opens the file for writing (append)p and then closes it again */
  539. boolean touch_file(filename)
  540. char *filename;
  541. /* return false if error, true otherwise. */
  542. {
  543.   FILE *stream = NULL;
  544.   if (filename == NULL)
  545.     return(false);
  546.   stream = s_fopen(filename, "a");
  547.   if (NULL == stream)
  548.     return(false);
  549.   else
  550.     { s_fclose(stream);
  551.       return(true);
  552.     }
  553. }
  554.  
  555. /*----------------------------------------------------------------------*/
  556.  
  557. char *merge_pathnames(pathname, directory)
  558. char *pathname;
  559. char *directory;
  560. {
  561.   /* if the pathname is not complete, then it puts on the directory
  562.      component and returns it in a static variable.  This is Unix specific */
  563.   static char answer[MAX_FILENAME_LEN + 1];
  564.   if((pathname[0] == '/') || (NULL == directory) || directory[0] == '\0')
  565.     return(pathname);
  566.   else{
  567.     answer[0] = '\0';
  568.     strncat(answer, directory, MAX_FILENAME_LEN);
  569. #ifdef WIN32
  570.     if(directory[strlen(directory) - 1] != '\\')
  571.       strncat(answer, "\\", MAX_FILENAME_LEN);
  572. #else
  573. #ifdef THINK_C
  574.     if(directory[strlen(directory) - 1] != ':')
  575.       strncat(answer, ":", MAX_FILENAME_LEN);
  576. #else
  577.     if(directory[strlen(directory) - 1] != '/')
  578.       strncat(answer, "/", MAX_FILENAME_LEN);
  579. #endif /* THINK_C */
  580. #endif /* WIN32 */
  581.     strncat(answer, pathname, MAX_FILENAME_LEN);
  582.   }
  583.   /* should this call truename? */
  584.   return(answer);
  585. }
  586.  
  587. /*----------------------------------------------------------------------*/
  588.  
  589.  
  590. boolean 
  591. read_string_from_file(stream,array,array_length)
  592. FILE *stream;
  593. char *array;
  594. long array_length;
  595. /* returns true if it wins. */
  596. {
  597.   long ch;
  598.   long char_count = 0;
  599.  
  600.   array[0] = '\0';
  601.   while(true){
  602.     ch = fgetc(stream);
  603.     if(EOF == ch){
  604.       array[char_count] = '\0';
  605.       return(false);
  606.     }
  607.     else if(char_count == array_length){        
  608.       array[char_count] = '\0';
  609.       return(false);
  610.     }
  611.     else if('\0' == ch){
  612.       array[char_count] = '\0';
  613.       return(true);
  614.     }
  615.     else
  616. #ifdef WIN32
  617.       array[char_count++] = (char)ch;
  618. #else          
  619.       array[char_count++] = ch;
  620. #endif
  621.   }
  622. }
  623.  
  624. /*----------------------------------------------------------------------*/
  625.  
  626. /* counts the lines in a file */
  627. long count_lines(stream)
  628. FILE *stream;
  629. {
  630.   long answer = 1;
  631.   char line[100];
  632.   fseek(stream, 0L, SEEK_SET);  
  633.   while(NULL != fgets(line,100L,stream))
  634.     answer++;
  635.   return(answer);
  636. }
  637.  
  638. #ifdef WIN32
  639. /*
  640.  *  Windows NT (and DOS and ...) won't allow open files to be renamed.
  641.  *  So this function closes the file, rename it, and reopens it.
  642.  */
  643. int CloseRenameOpen(FILE **ppf,char *oldname,char *newname,char *openmode) {
  644. int Result;
  645. long Position;
  646. char *cp, tmp_filename[MAX_FILENAME_LEN];
  647. int ch = '.';
  648.  
  649.   if (ppf!=NULL) {
  650.     /* Save file poiner position and close the file */
  651.     Position = ftell(*ppf);
  652.     s_fclose(*ppf);
  653.   }
  654.  
  655.   /* rename in NT has a different meaning from UNIX's */
  656.   /* the new name should not be exist */
  657.   tmp_filename[0] = 0;
  658.   if (access(newname, 0) == 0) {
  659.     /* change the new file name to a unique one */
  660.     strcpy(tmp_filename, newname);
  661.     if ((strlen(tmp_filename) + 6) >= MAX_FILENAME_LEN)
  662.       tmp_filename[MAX_FILENAME_LEN - 7] = 0;
  663.     cp = strchr(tmp_filename, ch);
  664.     if (cp)
  665.       strcpy(++cp, "XXXXXX");
  666.     else
  667.       strcat(tmp_filename, "XXXXXX");
  668.     _mktemp(tmp_filename);
  669.     Result = rename(newname,tmp_filename);
  670.     if (Result!=0)
  671.       return Result;
  672.   }
  673.     
  674.   /* Rename the file */
  675.   Result = rename(oldname, newname);
  676.   if (Result!=0) {
  677.     /* If failed, the newname file comes back */
  678.     if (tmp_filename[0] != 0)
  679.       rename(tmp_filename, newname);
  680.   } else {
  681.     /* If OK, delete the tmp_file */
  682.     if (tmp_filename[0] != 0)
  683.       unlink(tmp_filename);
  684.   }
  685.   /* Reopen it */
  686.   if (ppf!=NULL) {
  687.     if (Result!=0) {
  688.       /* Reopen oldname */
  689.       *ppf = s_fopen(oldname,openmode);
  690.     } else {
  691.       /* Reopen newname */
  692.       *ppf = s_fopen(newname,openmode);
  693.     }  
  694.     if (*ppf!=NULL) {
  695.       /* Reposition file pointer */
  696.       fseek(*ppf,Position,SEEK_SET);
  697.     }
  698.   }
  699.   return Result;
  700. }
  701.  
  702.  
  703. /*
  704.  *  Check whether this filename is OK to create.  Return non-0
  705.  *  if it is OK.
  706.  */
  707. int CanCreateLongFileNames(char *IndexFileName) {
  708. char TestFileName[MAX_FILENAME_LEN];
  709. FILE *pFile;
  710.  
  711.     strncpy(TestFileName,IndexFileName,MAX_FILENAME_LEN);
  712.     TestFileName[MAX_FILENAME_LEN-1] = '\0';
  713.     strncat(TestFileName,".longextension.0.1.test",MAX_FILENAME_LEN);
  714.     TestFileName[MAX_FILENAME_LEN-1] = '\0';
  715.     pFile = fs_fopen(TestFileName,"w");
  716.     if (pFile==NULL) return 0;
  717.     fs_fclose(pFile);
  718.     remove(TestFileName);
  719.     return 1;
  720. }
  721.  
  722. #endif
  723.  
  724. /*----------------------------------------------------------------------*/
  725.  
  726. #define UNCOMPRESSOR "zcat"
  727.  
  728.  
  729. char*
  730. fs_fzcat(fileName)
  731. char *fileName;
  732. /* uncompress the file fileName
  733.    returns a pointer to the name of the uncompressed file if succeeds
  734.    returns NULL if failed
  735. */
  736. {
  737.  
  738.  
  739.   char buffer[ 2 * MAX_FILENAME_LEN + 10 ];
  740.   long err = 0L;
  741.   
  742.  
  743. #if (defined(NeXT) || defined(Mach) || defined(BSD43))
  744.   char tmpFileName[MAX_FILENAME_LEN+1];
  745. #else
  746.   char *tmpFileName = NULL;
  747. #endif              /* NeXT or Mach */
  748.   char *retptr;
  749.  
  750.   if (fileName == NULL)
  751.     return(NULL);
  752.  
  753. #if defined(NeXT) || defined(Mach) || defined(BSD43)
  754.   tmpnam(tmpFileName);
  755.   retptr = s_strdup(tmpFileName);
  756. #else
  757.   tmpFileName = tempnam("/tmp/", 0);
  758.   retptr = tmpFileName;
  759.   if (! retptr) {
  760.     return(NULL);
  761.   }
  762. #endif
  763.  
  764.  
  765.     sprintf(buffer, "%s %s.Z > %s", UNCOMPRESSOR, fileName, retptr);
  766.  
  767.     system(buffer);
  768.     return(retptr); 
  769.  
  770.  
  771.  
  772. /*   
  773.     if( system(buffer) != 0 ) {
  774.         waislog(WLOG_HIGH, WLOG_ERROR, "Error excuting system command: %s %ld",buffer, err );
  775.     unlink(retptr);
  776.         s_free(retptr);
  777.         return(NULL);
  778.     }
  779.     else {    
  780.        return(retptr);
  781.     }
  782. */
  783.  
  784. }
  785.