#include <proto/exec.h>
#include <proto/dos.h>

struct DosLibrary *DOSBase;
const char verstag[] = "\0$VER: makelink.TV 42.2 (18.11.94)\n";

/* all on stack, so we can be resident */
/* TODO: Link loop detection like C='s makelink */

int MAIN(void) {
  int rc = 20;
  struct RDArgs *rda;
  struct {
    char *from;
    char *to;
    long hard;
    long force;
    long soft;
  } args = { NULL, NULL, 0, 0, 0 };
  BPTR lock;
  struct FileInfoBlock *fib;

  if (!(DOSBase = (void *)OpenLibrary("dos.library",37)))
    return 50;
  if (!(rda = ReadArgs("FROM/A,TO/A,HARD/S,FORCE/S,SOFT/S",(LONG *)&args,
		       NULL))) {
    PrintFault(IoErr(),NULL);
    goto quit0;
  }
  if (!(fib = AllocDosObject(DOS_FIB,NULL))) {
    PrintFault(ERROR_NO_FREE_STORE,NULL);
    goto quit1;
  }
  if (args.soft) {
    if (args.hard) {
      PutStr("Make up your mind, is it HARD or SOFT?\n");
      goto quit2;
    }
    if (!MakeLink(args.from,(LONG)args.to,LINK_SOFT)) {
      PrintFault(IoErr(),args.from);
      goto quit2;
    }
    rc = 0;
    goto quit2;
  } else {
    if (!(lock = Lock(args.to,SHARED_LOCK))) {
      PrintFault(IoErr(),args.to);
      goto quit2;
    }
    if (!Examine(lock,fib)) {
      PrintFault(IoErr(),args.to);
      goto quit3;
    }
    if (fib->fib_EntryType > 0) { /* link loop detection goes in here */
      if (!args.force) {
	PutStr("Links to directories require use of the FORCE keyword\n");
	goto quit3;
      }
    }
    if (!MakeLink(args.from,lock,LINK_HARD)) {
      PrintFault(IoErr(),args.from);
      goto quit3;
    }
    rc = 0;
  }
 quit3:
  UnLock(lock);
 quit2:
  FreeDosObject(DOS_FIB,fib);
 quit1:
  FreeArgs(rda);
 quit0:
  CloseLibrary((void *)DOSBase);
  return rc;
}
