/*
** File: AddSem.c
** Created:       04.04.97 Emmy
** Last Modified: 14.04.97 Emmy
** Version: 1.0
****************
** Add`s a semaphore to the public list.
**
** USAGE: [RUN] AddSem <SemaphoreName>
**
** Use BREAK to terminate the programm
**
** The program does not detach from the shell.
****************
** Idea:   Tobias Seiler (tabs@blader.com)
**         had the idea on the Computer Meeting in Rosenheim at April 97
** Coding: Emmeran "Emmy" Seehuber (es@mylius.com)
****************
** Compile using:
**  SAS/C:         (Object size: smallest; Exe size: smallest; Compiletime: middle)
**   sc link AddSem.c 
**  GNU C:         (Object size: middle; Exe size: largest; Compiletime: longest)
**   make
**  StormC:        (Object size: biggest; Exe size: middle; Compiletime: smallest)
**   Load the project and press <F8>
****************
** This software is subject to the "Standard Amiga FD-Software Copyright Note".
** It is MAILWARE as defined in paragraph 4.b.
** For more information please read "AFD-COPYRIGHT" (Version 1 or higher).
**
** Please send me an EMail ! (I`d like to get mails !!!!!)
****************
** Copyright (c) 1997 by Emmy
*/

static char *pszVersionInfo = "\0$VER:AddSem 1.0 (14.4.97)";

// Just some includes:
#include <exec/exec.h>
#include <exec/semaphores.h>
#include <proto/exec.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <dos/dos.h>
#include <proto/dos.h>
#include <pragmas/dos_pragmas.h>


// Parameter Synatx
#define PARA_TEMPLATE "SEMAPHORENAME/A"

// Structure to hold the Arguments
struct MainArgs {
  char *m_pszSemaphoreName;       // Name of the semaphore
};

// The main()
int main(int argc, char **argv)
/***********************************************************************************/
{ /// main
  // Take the memory for all variables from the stack
  struct SignalSemaphore MySemaphore;
  struct MainArgs ma;
  struct RDArgs *pArgs;
  ULONG lRetCode = 0;

  // Clear Memory of MainArgs
  memset( &ma, 0, sizeof( struct MainArgs ) );

  // Parse the Args
  pArgs = ReadArgs( PARA_TEMPLATE, (LONG *) &ma, NULL );

  // Parsing ok ?
  if( pArgs ) {

    // Do Work:

    // Check: Does the semaphore already exists ?
    if( FindSemaphore( ma.m_pszSemaphoreName ) ) {
      // I`dont want to use printf, because we can save the 2500 bytes(SAS/C) or
      // the 2200 bytes (GNU C + ixemul) or the 5000 bytes (GNU C + libnix)
      // >printf( "AddSem: Public semaphore \"%s\" does already exists!\n",
      // >          ma.m_pszSemaphoreName );
      char cHelp[1025]; // This MUST be enough
      strcpy( cHelp, "AddSem: Public semaphore \"" );
      strncat( cHelp, ma.m_pszSemaphoreName, 1024 );
      strncat( cHelp, "\" does already exists!\n", 1024 );
      FPuts( Output(), cHelp ); // AmigaDOS-Call

      lRetCode = 20;  // Set the Errorcode
    }
    else {
      // Initialize the Public Semaphore
      //
      // We just only need to initialize the ln_Name-Field
      // of the Node, which is used to hold the semaphore in a
      // list.
      MySemaphore.ss_Link.ln_Name = ma.m_pszSemaphoreName;
      MySemaphore.ss_Link.ln_Pri = 0; // Just a normal priority

      // Add the semaphore to the public list:
      // NOTE: AddSemaphore() requires OS 2.0 or higger !
      AddSemaphore( &MySemaphore );

      // Wait until the BREAK-Signal occurs:

      // SIGBREAKB_CTRL_C is just only the NUMBER(12) of the
      // signal bit. We must do a 1<<SIGBREAKB_CTRL_C to get
      // the signal mask.
      Wait( 1<<SIGBREAKB_CTRL_C ); // Wait until CTRL-C

      // Now Cleanup&Quit:

      // Remove the seamphore
      // We can only remove the semaphore, when nobody uses it.
      // But: Removing a public semaphore is always a little critcal,
      //      because a process, which has already used the semaphore
      //      can crash, when it uses a "buffered" pointer to the semaphore.
      //      (It better should do a FindSemaphore() before each ObtainSemaphore())

      // Forbid Multitasking
      Forbid(); // Sorry, but this MUST be

      // Lock the semaphore !
      ObtainSemaphore( &MySemaphore ); // Wait for locking the Semaphore

      // Remove the semaphore from the public list:
      RemSemaphore( &MySemaphore );

      // Permit Multitasking
      Permit();

    } // if( FindSemaphore ) ... else

    // Free the RDArgs-Structure returned from ReadArgs
    FreeArgs( pArgs );
  }
  else {// No ?!? -> Print the errormessage
    PrintFault( IoErr(), "AddSem" );
    lRetCode = 20;  // -> Set the errorcode
  }

  // Return the errorcode
  return(lRetCode);
} /// main

/* EOF */

