home *** CD-ROM | disk | FTP | other *** search
- /* C.Mktemp: Make a temporary file name */
-
- #include <string.h>
- #include <stdlib.h>
- #include "kernel.h"
- #include "swis.h"
-
- #define ReadCat 5
-
- /* Create a temporary file name by adding a directory prefix to file.
- * If the external variable temp_dir is not zero, this directory will be
- * used. Otherwise, the following are used, in order.
- * 1. <Tmp$Dir>
- * 2. &.Tmp
- * 3. The current directory.
- * The function returns zero on an error (temp_dir is not a directory, or
- * malloc() failed), otherwise it returns a malloc-ed string containing
- * the required name.
- */
-
- static char *concat (const char *dir, const char *file);
-
- char *temp_dir = 0;
-
- char *mktemp (const char *file)
- {
- char *dir;
- char *name;
- char buf[11];
- int len = strlen(file);
- _kernel_osfile_block blk;
- _kernel_swi_regs regs;
-
- /* Is the supplied filename a pure file name? */
- if (len > 10)
- return 0;
-
- /* Pad out the supplied filename on the left with a unique ID
- * (Based on the program start time)
- */
- if (len < 10 && _kernel_swi(OS_GetEnv,®s,®s) == NULL)
- {
- int i;
- char *time = (char *)regs.r[2];
-
- strcpy(buf,file);
-
- for (i = len; i < 10; ++i)
- {
- char c = time[(9 - i) >> 1];
-
- if (i & 1)
- c >>= 4;
-
- c &= 0x0F;
- buf[i] = "abcdefghijklmnop"[c];
- }
-
- buf[10] = 0;
-
- file = buf;
- }
-
- /* First, try the supplied directory */
- if ( temp_dir )
- {
- if ( _kernel_osfile(ReadCat,temp_dir,&blk) == 2 )
- return concat(temp_dir,file);
- else
- {
- /* Is it a filing system name only? */
- len = strlen(temp_dir);
-
- if (temp_dir[len-1] != ':')
- return 0;
-
- /* One extra, just in case file == "", for the '@' */
- name = malloc(len + strlen(file) + 2);
-
- if (name == 0)
- return 0;
-
- strcpy(name,temp_dir);
- name[len] = '@';
- name[len+1] = '\0';
-
- if (_kernel_osfile(ReadCat,name,&blk) != 2)
- {
- free(name);
- return 0;
- }
-
- strcpy(&name[len],file);
- return name;
- }
- }
-
- /* Otherwise, go through the list... */
-
- /* First of all, try <Tmp$Dir> */
- if ((dir = getenv("Tmp$Dir")) != 0)
- {
- if (_kernel_osfile(ReadCat,dir,&blk) == 2)
- return concat(dir,file);
- else
- {
- /* Is it a filing system name only? */
- len = strlen(dir);
-
- if (dir[len-1] != ':')
- goto no_go;
-
- /* One extra, just in case file == "", for the '@' */
- name = malloc(len + strlen(file) + 2);
-
- if (name == 0)
- goto no_go;
-
- strcpy(name,dir);
- name[len] = '@';
- name[len+1] = '\0';
-
- if (_kernel_osfile(ReadCat,name,&blk) != 2)
- {
- free(name);
- goto no_go;
- }
-
- strcpy(&name[len],file);
- return name;
- }
- }
-
- no_go:
- /* No <Tmp$Dir>, so try &.Tmp, if it exists */
- if (_kernel_osfile(ReadCat,"&.Tmp",&blk) == 2)
- return concat("&.Tmp",file);
-
- /* Out of luck - use the current directory */
- name = malloc(strlen(file)+1);
- if ( name )
- strcpy(name,file);
-
- return name;
- }
-
- static char *concat (const char *dir, const char *file)
- {
- char *result = malloc(strlen(dir)+strlen(file)+2);
- char *p = result;
-
- if ( result == 0 )
- return 0;
-
- while ( *dir )
- *p++ = *dir++;
-
- *p++ = '.';
- while ( *file )
- *p++ = *file++;
-
- *p = '\0';
-
- return result;
- }
-
- /* ----------------------------------------------------------------- */
-
- #ifdef test
-
- #include <stdio.h>
-
- int main (int argc, char *argv[])
- {
- char *tmp;
-
- if ( argc != 2 && argc != 3 )
- {
- fprintf(stderr,"Usage: %s file [dir]\n",argv[0]);
- return 1;
- }
-
- if ( argc == 3 )
- temp_dir = argv[2];
-
- tmp = mktemp (argv[1]);
-
- printf("Temp file = %s\n", tmp ? tmp : "<Not possible>");
-
- return 0;
- }
-
- #endif
-