Esempio n. 1
0
DH_FILE * dh_open(char path[])
{
 DH_FILE * dh_file = NULL;
 FILE_ENTRY * fptr;
 char filename[MAX_PATHNAME_LEN+1];
 char pathname[MAX_PATHNAME_LEN+1];
 short int i;
 char * p;
 struct DH_HEADER header;
 struct DH_AK_HEADER ak_header;
 char * ibuff = NULL;
 short int file_id = -1;
 OSFILE fu = INVALID_FILE_HANDLE;      /* Primary subfile */
 OSFILE ofu = INVALID_FILE_HANDLE;     /* Overflow subfile */
 int bytes;
 unsigned long int ak_map;
 short int no_of_subfiles;
 short int no_of_aks;
 bool read_only = FALSE;
 DESCRIPTOR * descr;
 int n;
 int subfile;
 long int ak_node_num;
 OBJECT_HEADER * obj;
 struct stat statbuf;
 unsigned long int device = 0;
 unsigned long int inode = 0;

 dh_err = 0;
 process.os_error = 0;

 /* Validate file name */

 p = strrchr(path, DS);          /* Find final directory separator */
 if (p == NULL) p = path;
 if ((*p == '\0')                  /* Null name in last component */
    || !fullpath(filename, path))  /* Unable to map to absolute pathname */
  {
   dh_err = DHE_FILE_NOT_FOUND;
   goto exit_dh_open;
  }

 /* Check if this file is already open to this process */

 if (stat(filename, &statbuf) != 0)
  {
   dh_err = DHE_FILE_NOT_FOUND;
   goto exit_dh_open;
  }
 device = statbuf.st_dev;
 inode = statbuf.st_ino;

 for (dh_file = dh_file_head; dh_file != NULL; dh_file = dh_file->next_file)
  {
   fptr = FPtr(dh_file->file_id);
   if ((device == 0) && (inode == 0))  /* Compare by name */
    {
     if (strcmp((char *)(fptr->pathname), filename) != 0) continue;
    }
   else
    {
     if ((fptr->device != device) || (fptr->inode != inode)) continue;
    }

   /* Found a match */

   if (fptr->ref_ct < 0)   /* Already open for exclusive access */
    {
     dh_err = DHE_EXCLUSIVE;
     goto exit_dh_open;
    }

   dh_file->open_count++;
   goto exit_dh_open;
  }

 /* Open primary subfile */

 sprintf(pathname, "%s%c~0", filename, DS);
 if (access(pathname, 2)) read_only = TRUE;

 fu = dio_open(pathname, (read_only)?DIO_READ:DIO_UPDATE);
 if (!ValidFileHandle(fu))
  {
   dh_err = DHE_FILE_NOT_FOUND;
   goto exit_dh_open;
  }

 /* Validate primary subfile header */

 if (Read(fu, (char *)(&header), DH_HEADER_SIZE) < 0)
  {
   dh_err = DHE_READ_ERROR;
   process.os_error = OSError;
   goto exit_dh_open;
  }

 switch(header.magic)
  {
   case DH_PRIMARY:
      if (header.hash)
       {
        dh_err = DHE_HASH_TYPE;
        goto exit_dh_open;
       }
      break;
   default:
      dh_err = DHE_PSFH_FAULT;
      goto exit_dh_open;
  }

 if ((header.flags & DHF_TRUSTED)    /* Access requires trusted status */
    && (!(process.program.flags & HDR_IS_TRUSTED)))
  {
   dh_err = DHE_TRUSTED;
   goto exit_dh_open;
  }

 /* !!FILE_VERSION!! */
 if (header.file_version > DH_VERSION)
  {
   dh_err = DHE_VERSION;
   goto exit_dh_open;
  }

 /* Check if this file may contain a record id longer than the maximum
    we can support.  The longest_id element of the DH_PARAMS structure
    is set to the length of the longest id written to the file.  This
    record may not be there anymore.  QMFix will sort this out.         */

 if ((header.file_version > 0)
    && (header.params.longest_id > sysseg->maxidlen))
  {
   dh_err = DHE_ID_LEN;
   goto exit_dh_open;
  }

 /* Open overflow subfile */

 sprintf(pathname, "%s%c~1", filename, DS);
 if (access(pathname, 2)) read_only = TRUE;

 ofu = dio_open(pathname, (read_only)?DIO_READ:DIO_UPDATE);
 if (!ValidFileHandle(ofu))
  {
   dh_err = DHE_FILE_NOT_FOUND;
   goto exit_dh_open;
  }

 /* Allocate new DH_FILE structure
    AKs use subfile numbers from AK_BASE_SUBFILE upwards, based on position
    in the AK map. Because AKs can be deleted, there may be gaps in the
    numbering. At this stage, simply find the highest used AK number so that
    we know how big the data structures need to be. We will go through the
    map again once we have created the AK data array.                                          */

 no_of_aks = 0;
 for(i = 0, ak_map = header.ak_map; i < MAX_INDICES; i++, ak_map = ak_map >> 1)
  {
   if (ak_map & 1) no_of_aks = i + 1;  /* Not really  -  There may be gaps */
  }
 no_of_subfiles = AK_BASE_SUBFILE + no_of_aks;

 bytes = sizeof(struct DH_FILE)
         + (sizeof(struct SUBFILE_INFO) * (no_of_subfiles - 1));
 dh_file = (DH_FILE *)k_alloc(9,bytes);
 if (dh_file == NULL)
  {
   dh_err = DHE_OPEN_NO_MEMORY;
   goto exit_dh_open;
  }

 for (i = 0; i < no_of_subfiles; i++) dh_file->sf[i].fu = INVALID_FILE_HANDLE;

 dh_file->file_version = header.file_version;
 dh_file->header_bytes = DHHeaderSize(header.file_version, header.group_size);
 dh_file->ak_header_bytes = AKHeaderSize(header.file_version);
 dh_file->group_size = header.group_size;

 dh_file->no_of_subfiles = no_of_subfiles;
 dh_file->open_count = 1;
 dh_file->flags = 0;
 dh_file->ak_map = header.ak_map;
 dh_file->trigger_name = NULL;
 dh_file->trigger = NULL;
 dh_file->trigger_modes = 0;

 if (read_only) dh_file->flags |= DHF_RDONLY;        /* Read only */



 if (header.akpath[0] == '\0') dh_file->akpath = NULL;
 else
  {
   dh_file->akpath = (char *)k_alloc(106, strlen(header.akpath) + 1);
   strcpy(dh_file->akpath, header.akpath);
  }

 /* Transfer file units into DH_FILE structure so that we do not have
    to open them again on the first access.                           */

 dh_set_subfile(dh_file, PRIMARY_SUBFILE, fu);
 fu = INVALID_FILE_HANDLE;

 dh_set_subfile(dh_file, OVERFLOW_SUBFILE, ofu);
 ofu = INVALID_FILE_HANDLE;

 /* Load trigger function, if any */

 if (header.trigger_name[0] != '\0')
  {
   dh_file->trigger_name = (char *)k_alloc(69,strlen(header.trigger_name) + 1); /* 0259 */
   strcpy(dh_file->trigger_name, header.trigger_name);

   /* Attempt to snap link to trigger function */

   obj = (OBJECT_HEADER *)load_object(header.trigger_name, FALSE);
   if (obj != NULL) obj->ext_hdr.prog.refs += 1;
   dh_file->trigger = (u_char *)obj;
   dh_file->flags |= DHF_TRIGGER;
 
   /* Copy the trigger mode flags. If this file pre-dates the introduction
      of these flags, the byte will be zero. Set the defaults to be as they
      were for old versions of the system.                                 */

   if (header.trigger_modes) dh_file->trigger_modes = header.trigger_modes;
   else dh_file->trigger_modes = TRG_PRE_WRITE | TRG_PRE_DELETE;
  }

 /* Now process any AK indices */

 if (no_of_aks)      /* Has AK indices */
  {
   dh_file->flags |= DHF_AK;

   /* Set up AK data matrix */

   dh_file->ak_data = a_alloc(no_of_aks, AKD_COLS, TRUE);

   for(i = 0, ak_map = header.ak_map; i < no_of_aks; i++, ak_map = ak_map >> 1)
    {
     /* AK field name - Set as null string for now, filled in for used
        entries after we have validated the subfile.                    */

     descr = Element(dh_file->ak_data, (i * AKD_COLS) + AKD_NAME);
     InitDescr(descr, STRING);
     descr->data.str.saddr = NULL;
   
     if (ak_map & 1)
      {
       /* Open AK subfile and validate header */

       subfile = i + AK_BASE_SUBFILE;
       if (!dh_open_subfile(dh_file, filename, subfile, FALSE))
        {
         dh_err = DHE_AK_NOT_FOUND;
         goto exit_dh_open;
        }

       if (!dh_read_group(dh_file, subfile, 0, (char *)(&ak_header),
            DH_AK_HEADER_SIZE))
        {
         dh_err = DHE_AK_HDR_READ_ERROR;
         process.os_error = OSError;
         goto exit_dh_open;
        }

       if (ak_header.magic != DH_INDEX)
        {
         dh_err = DHE_AK_HDR_FAULT;
         goto exit_dh_open;
        }

       /* Cross-check the index subfile with the primary data subfile */

       if (header.creation_timestamp != ak_header.data_creation_timestamp)
        {
         dh_err = DHE_AK_CROSS_CHECK;
         goto exit_dh_open;
        }

       /* Fill in AK name */

       ts_init(&(descr->data.str.saddr), strlen(ak_header.ak_name));
       ts_copy_c_string(ak_header.ak_name);
       (void)ts_terminate();

       /* Field number */

       descr = Element(dh_file->ak_data, (i * AKD_COLS) + AKD_FNO);
       InitDescr(descr, INTEGER);
       descr->data.value = ak_header.fno;

       /* Flags */

       descr = Element(dh_file->ak_data, (i * AKD_COLS) + AKD_FLGS);
       InitDescr(descr, INTEGER);
       descr->data.value = ak_header.flags;

       /* I-type code */

       descr = Element(dh_file->ak_data, (i * AKD_COLS) + AKD_OBJ);
       InitDescr(descr, STRING);
       descr->data.str.saddr = NULL;
       ts_init(&(descr->data.str.saddr), ak_header.itype_len);

       ak_node_num = GetAKFwdLink(dh_file, ak_header.itype_ptr);
       if (ak_node_num != 0)   /* Long expression */
        {
         /* Fetch I-type from separate node */

         ibuff = (char *)k_alloc(53, DH_AK_NODE_SIZE);
         do {
             if (!dh_read_group(dh_file, subfile, ak_node_num, ibuff,
                  DH_AK_NODE_SIZE))
              {
               goto exit_dh_open;
              }

             n = ((DH_ITYPE_NODE *)ibuff)->used_bytes - offsetof(DH_ITYPE_NODE, data);
             ts_copy((char *)(((DH_ITYPE_NODE *)ibuff)->data), n);
             ak_node_num = GetAKFwdLink(dh_file, ((DH_ITYPE_NODE *)ibuff)->next);
            } while(ak_node_num);
        }
       else
        {
         ts_copy((char *)ak_header.itype, ak_header.itype_len);
        }
       (void)ts_terminate();

       descr->data.str.saddr = s_make_contiguous(descr->data.str.saddr, NULL);

       /* Collation map name */

       descr = Element(dh_file->ak_data, (i * AKD_COLS) + AKD_MAPNAME);
       InitDescr(descr, STRING);
       k_put_c_string(ak_header.collation_map_name, descr);

       /* Collation map (contiguous string) */

       descr = Element(dh_file->ak_data, (i * AKD_COLS) + AKD_MAP);
       if (ak_header.collation_map_name[0] == '\0')
        {
         InitDescr(descr, STRING);
         descr->data.str.saddr = NULL;
        }
       else
        {
         k_put_string(ak_header.collation_map, 256, descr);
        }
      }
    }
  }
 else
  {
Esempio n. 2
0
bool dh_create_file(
   char path[],
   short int group_size,   /* -ve sets default */
   long int min_modulus,   /* -ve sets default */
   long int big_rec_size,  /* -ve sets default */
   short int merge_load,   /* -ve sets default */
   short int split_load,   /* -ve sets default */
   unsigned long int flags,
   short int version)      /* -ve sets default */
{
 bool status = FALSE;
 char primary_subfile[MAX_PATHNAME_LEN+1];
 char overflow_subfile[MAX_PATHNAME_LEN+1];
 bool primary_subfile_created = FALSE;
 bool overflow_subfile_created = FALSE;
 OSFILE fu = INVALID_FILE_HANDLE;
 struct DH_HEADER header;
 int header_bytes;
 int group_size_bytes;
 long int group;
 double file_size;

 dh_err = 0;
 process.os_error = 0;

 /* Validate arguments */

 if (group_size < 0)
  {
   group_size = DEFAULT_GROUP_SIZE;
  }
 else if ((group_size < 1) || (group_size > MAX_GROUP_SIZE))
  {
   dh_err = DHE_ILLEGAL_GROUP_SIZE;
   goto exit_dh_create_file;
  }
 group_size_bytes = group_size * DH_GROUP_MULTIPLIER;

 if (min_modulus < 1)
  {
   min_modulus = DEFAULT_MIN_MODULUS;
  }
 else if (min_modulus < 1)
  {
   dh_err = DHE_ILLEGAL_MIN_MODULUS;
   goto exit_dh_create_file;
  }

 if (big_rec_size < 0)
  {
   big_rec_size = (long)((group_size_bytes) * 0.8);
  }
 else if (big_rec_size > group_size_bytes - BLOCK_HEADER_SIZE)
  {
   big_rec_size = group_size_bytes - BLOCK_HEADER_SIZE;
  }

 if (merge_load < 0)
  {
   merge_load = DEFAULT_MERGE_LOAD;
  }
 else if (merge_load > 99)
  {
   dh_err = DHE_ILLEGAL_MERGE_LOAD;
   goto exit_dh_create_file;
  }

 if (split_load < 0)
  {
   split_load = DEFAULT_SPLIT_LOAD;
  }
 else if (split_load <= merge_load)
  {
   dh_err = DHE_ILLEGAL_SPLIT_LOAD;
   goto exit_dh_create_file;
  }

 /* !!FILE_VERSION!! */
 if (version < 0)
  {
   version = DH_VERSION;
  }
 else if (version > DH_VERSION)
  {
   dh_err = DHE_VERSION;
   goto exit_dh_create_file;
  }

 header_bytes = DHHeaderSize(version, group_size_bytes);

 if (version < 2)
  {
   /* Check if file exceeds 2Gb */

   file_size = (((double)group_size_bytes) * min_modulus) + header_bytes;
   if (file_size > (unsigned long)0x80000000L)
    {
     dh_err = DHE_SIZE;
     goto exit_dh_create_file;
    }
  }

 /* Check if directory to hold subfiles exists */

 if (access(path, 0) == 0)
  {
   dh_err = DHE_FILE_EXISTS;
   goto exit_dh_create_file;
  }

 /* Create directory */

 if (!make_path(path))
  {
   dh_err = DHE_CREATE_DIR_ERR;
   process.os_error = OSError;
   goto exit_dh_create_file;
  }

 /* Create primary subfile */

 sprintf(primary_subfile, "%s%c~0", path, DS);
 fu = dio_open(primary_subfile, DIO_NEW);

 if (!ValidFileHandle(fu))
  {
   dh_err = DHE_CREATE0_ERR; 
   process.os_error = OSError;
   goto exit_dh_create_file;   
  }

 primary_subfile_created = TRUE;

 /* Write primary subfile header */

 memset((char *)&header, 0, sizeof(header));
 header.magic = DH_PRIMARY;
 header.file_version = (u_char)version;
 header.group_size = group_size_bytes;
 header.flags = (unsigned short int)(flags & DHF_CREATE);
 header.params.modulus = min_modulus;
 header.params.min_modulus = min_modulus;
 header.params.big_rec_size = big_rec_size;
 header.params.split_load = split_load;
 header.params.merge_load = merge_load;
 header.params.load_bytes = 0;
 header.params.extended_load_bytes = 0;
 header.params.free_chain = 0;
 header.creation_timestamp = qmtime();
 header.record_count = 1;   /* Actually zero, see dh_fmt.h */

 /* Calculate mod_value as next power of two >= min_modulus */

 for (header.params.mod_value = 1;
      header.params.mod_value < min_modulus;
      header.params.mod_value <<= 1) {}

 memset(dh_buffer, 0, header_bytes);
 memcpy(dh_buffer, (char *)(&header), sizeof(header));
 if (Write(fu, dh_buffer, header_bytes) < 0)
  {
   dh_err = DHE_PSFH_WRITE_ERROR;
   process.os_error = OSError;
   goto exit_dh_create_file;
  }

 /* Initialise data groups */

 memset(dh_buffer, 0, group_size_bytes);
 ((DH_BLOCK *)(dh_buffer))->used_bytes = BLOCK_HEADER_SIZE;
 ((DH_BLOCK *)(dh_buffer))->block_type = DHT_DATA;

 for (group = 1; group <= min_modulus; group++)
  {
   if (Write(fu, dh_buffer, group_size_bytes) < 0)
    {
     dh_err = DHE_INIT_DATA_ERROR;
     process.os_error = OSError;
     goto exit_dh_create_file;
    }
  }

 CloseFile(fu);
 fu = INVALID_FILE_HANDLE;

 /* Create overflow subfile */

 sprintf(overflow_subfile, "%s%c~1", path, DS);
 fu = dio_open(overflow_subfile, DIO_NEW);

 if (!ValidFileHandle(fu))
  {
   dh_err = DHE_CREATE1_ERR; 
   process.os_error = OSError;
   goto exit_dh_create_file;
  }

 /* Write overflow subfile header */

 memset((char *)(&header), 0 , sizeof(header));
 header.magic = DH_OVERFLOW;
 header.group_size = group_size_bytes;

 memset(dh_buffer, 0, header_bytes);
 memcpy(dh_buffer, (char *)(&header), sizeof(header));

 if (Write(fu, dh_buffer, header_bytes) < 0)
  {
   dh_err = DHE_OSFH_WRITE_ERROR;
   process.os_error = OSError;
   goto exit_dh_create_file;
  }

 CloseFile(fu);
 fu = INVALID_FILE_HANDLE;

 status = TRUE;

exit_dh_create_file:
 if (status == FALSE)
  {
   if (ValidFileHandle(fu)) CloseFile(fu);

   if (primary_subfile_created) remove(primary_subfile);

   if (overflow_subfile_created) remove(overflow_subfile);
  }

 return status;
}
Esempio n. 3
0
int main (int argc, const char* argv[])
{
    unsigned char SourceId;
    unsigned char TargetId;
    dhandle_t     Source = NULL;
    dhandle_t     Target = NULL;
    unsigned int  SectSize;
    unsigned int  SectCount;
    char*         Buffer;
    unsigned int  Sector;
    unsigned int  ChunkCount;
    unsigned int  ChunkOffset = 0;

    clrscr ();
    screensize (&ScreenX, &ScreenY);

    /* Allow user to read exit messages */
    if (doesclrscrafterexit ()) {
        atexit ((void (*)) cgetc);
    }

    cputs ("Floppy Disk Copy\r\n");
    chline (16);
    cputs ("\r\n");

    /* Get source and target drive id (which may very well be identical) */
    switch (argc) {
      case 1:
        SourceId = AskForDrive ("Source");
        TargetId = AskForDrive ("Target");
        cputs ("\r\n");
        break;

      case 2:
        SourceId = TargetId = atoi (argv[1]);
        break;

      case 3:
        SourceId = atoi (argv[1]);
        TargetId = atoi (argv[2]);
        break;

      default:
        cprintf ("\r\nToo many arguments\r\n");
        return EXIT_FAILURE;
    }

    cputs ("\r\n");

    do {
        /* Check for single drive copy or inital iteration */
        if (SourceId == TargetId || Source == NULL) {
            AskForDisk ("Source", SourceId);
        }

        /* Check for initial iteration */
        if (Source == NULL) {

            /* Open source drive */
            Source = dio_open (SourceId);
            if (Source == NULL) {
                cprintf ("\r\n\nError %d on opening Drive %d\r\n", (int) _oserror, SourceId);
                return EXIT_FAILURE;
            }

            SectSize  = dio_query_sectsize (Source);
            SectCount = dio_query_sectcount (Source);

            /* Allocate buffer */
            Buffer = AllocBuffer (SectSize, SectCount, &ChunkCount);
            if (Buffer == NULL) {
                cputs ("\r\n\nError on allocating Buffer\r\n");
                return EXIT_FAILURE;
            }
        }

        ClearLine ();

        /* Read one chunk of sectors into buffer */
        for (Sector = ChunkOffset; Sector < SectCount && (Sector - ChunkOffset) < ChunkCount; ++Sector) {
            cprintf ("\rReading Sector %d of %d", Sector + 1, SectCount);

            /* Read one sector */
            if (dio_read (Source, Sector, Buffer + (Sector - ChunkOffset) * SectSize) != 0) {
                cprintf ("\r\n\nError %d on reading from Drive %d\r\n", (int) _oserror, SourceId);
                return EXIT_FAILURE;
            }
        }

        /* Check for single drive copy or inital iteration */
        if (TargetId == SourceId || Target == NULL) {
            AskForDisk ("Target", TargetId);
        }

        /* Open target drive on initial iteration */
        if (Target == NULL) {
            Target = dio_open (TargetId);
            if (Target == NULL) {
                cprintf ("\r\n\nError %d on opening Drive %d\r\n", (int) _oserror, TargetId);
                return EXIT_FAILURE;
            }

            /* Check for compatible drives */
            if (dio_query_sectsize (Target)  != SectSize ||
                dio_query_sectcount (Target) != SectCount) {
                cputs ("\r\n\nFormat mismatch between Drives\r\n");
                return EXIT_FAILURE;
            }
        }

        ClearLine ();

        /* Write one chunk of sectors from buffer */
        for (Sector = ChunkOffset; Sector < SectCount && (Sector - ChunkOffset) < ChunkCount; ++Sector) {
            cprintf ("\rWriting Sector %d of %d", Sector + 1, SectCount);

            /* Write one sector */
            if (dio_write (Target, Sector, Buffer + (Sector - ChunkOffset) * SectSize) != 0) {
                cprintf ("\r\n\nError %d on writing to Drive %d\r\n", (int) _oserror, TargetId);
                return EXIT_FAILURE;
            }
        }

        /* Advance to next chunk */
        ChunkOffset += ChunkCount;

    } while (Sector < SectCount);

    ClearLine ();
    cprintf ("\rSuccessfully copied %d Sectors\r\n", SectCount);

    free (Buffer);
    dio_close (Source);
    dio_close (Target);

    return EXIT_SUCCESS;
}
Esempio n. 4
0
void log_message(char * msg)
{
 OSFILE errlog;
 time_t timenow;
 struct tm * ltime;
 int bytes;
 int src;
 int dst;
#define BUFF_SIZE 4096
 char buff[BUFF_SIZE];
 char * p;

 if (sysseg->errlog)
  {
   StartExclusive(ERRLOG_SEM, 66);

   sprintf(buff, "%s%cerrlog", sysseg->sysdir, DS);
   errlog = dio_open(buff, DIO_OVERWRITE);

   if (ValidFileHandle(errlog))
    {
     if (filelength64(errlog) >= sysseg->errlog)
      {
       /* Must trim front from log file */

       src = sysseg->errlog / 2;     /* Move from here... */
       dst = 0;                      /* ...to here */

       Seek(errlog, src, SEEK_SET);
       bytes = Read(errlog, buff, BUFF_SIZE);
       src += bytes;

       /* Find the first newline (there must be one) */

       p = ((char *)memchr(buff, '\n', bytes)) + 1;
       bytes -= (p - buff);                /* Bytes to copy */

       do {
           Seek(errlog, dst, SEEK_SET);
           dst += Write(errlog, p, bytes);

           Seek(errlog, src, SEEK_SET);
           bytes = Read(errlog, buff, BUFF_SIZE);

           src += bytes;
           p = buff;
          } while(bytes > 0);

       /* Truncate the file */       

       chsize64(errlog, dst);
      }

     Seek(errlog, 0, SEEK_END);

     timenow = time(NULL);
     ltime = localtime(&timenow);

     /* The buffer trimming mechanism above requires that the file is
        opened in binary mode on Windows systems otherwise the destination
        pointer loses track because Windows is busy modifying the data
        written to the file. Therefore, we must do our own handling of
        the CRLF newline pair on Windows. To do this in a platform
        independent way, we use the Newline macro in the sprintf() below
        instead of the more obvious use of \n.                            */

     if (my_uptr != NULL)
      {
       bytes = sprintf(buff, "%02d %.3s %02d %02d:%02d:%02d User %d (pid %ld, %s):%s   %s%s",
               ltime->tm_mday,
               month_names[ltime->tm_mon],
               ltime->tm_year % 100,
               ltime->tm_hour,
               ltime->tm_min,
               ltime->tm_sec,
               my_uptr->uid,
               my_uptr->pid,
               my_uptr->username,
               Newline,
               msg,
               Newline);
      }
     else
      {
       bytes = sprintf(buff, "%02d %.3s %02d %02d:%02d:%02d:%s   %s%s",
               ltime->tm_mday,
               month_names[ltime->tm_mon],
               ltime->tm_year % 100,
               ltime->tm_hour,
               ltime->tm_min,
               ltime->tm_sec,
               Newline,
               msg,
               Newline);
      }

     Write(errlog, buff, bytes);

     CloseFile(errlog);  /* 0423 */
    }

   EndExclusive(ERRLOG_SEM);
  }
}