[project @ 2005-12-15 10:36:03 by simonmar]
[ghc-hetmet.git] / glafp-utils / lndir / lndir.c
index 0d77a49..8da535e 100644 (file)
@@ -69,6 +69,10 @@ in this Software without prior written authorization from the X Consortium.
 #define MAXPATHLEN 2048
 #endif
 
+#ifdef __CYGWIN32__
+#include <sys/cygwin.h>
+#endif
+
 #if NeedVarargsPrototypes
 #include <stdarg.h>
 #endif
@@ -82,6 +86,8 @@ int ignore_links = 0;         /* -ignorelinks */
 char *rcurdir;
 char *curdir;
 
+int force=0;
+
 void
 quit (
 #if NeedVarargsPrototypes
@@ -224,7 +230,9 @@ int rel;                    /* if true, prepend "../" to fn before using */
 #endif
            {
                /* directory */
+#ifndef __CYGWIN32__   /* don't trust cygwin's n_dirs count */
                n_dirs--;
+#endif
                if (dp->d_name[0] == '.' &&
                    (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' &&
                                               dp->d_name[2] == '\0')))
@@ -235,6 +243,10 @@ int rel;                   /* if true, prepend "../" to fn before using */
                    continue;
                if (!strcmp (dp->d_name, "CVS"))
                    continue;
+               if (!strcmp (dp->d_name, ".svn"))
+                   continue;
+               if (!strcmp (dp->d_name, "_darcs"))
+                   continue;
                if (!strcmp (dp->d_name, "CVS.adm"))
                    continue;
                ocurdir = rcurdir;
@@ -284,15 +296,22 @@ int rel;                  /* if true, prepend "../" to fn before using */
        }
 
        if (symlen >= 0) {
-           /* Link exists in new tree.  Print message if it doesn't match. */
-           if (!equivalent (basesymlen>=0 ? basesym : buf, symbuf))
-               msg ("%s: %s", dp->d_name, symbuf);
-       } else {
-           if (symlink (basesymlen>=0 ? basesym : buf, dp->d_name) < 0)
+         if (!equivalent (basesymlen>=0 ? basesym : buf, symbuf)) {
+           if (force) {
+             unlink(dp->d_name);
+             if (symlink (basesymlen>=0 ? basesym : buf, dp->d_name) < 0)
                mperror (dp->d_name);
+           } else {
+             /* Link exists in new tree.  Print message if it doesn't match. */
+             msg ("%s: %s", dp->d_name, symbuf);
+           }
+         }
+       } else {
+         if (symlink (basesymlen>=0 ? basesym : buf, dp->d_name) < 0)
+           mperror (dp->d_name);
        }
     }
-
+    
     closedir (df);
     return 0;
 }
@@ -303,41 +322,65 @@ int ac;
 char **av;
 {
     char *prog_name = av[0];
-    char *fn, *tn;
+    char* tn;
     struct stat fs, ts;
+#ifdef __CYGWIN32__
+    /*   
+    The lndir code assumes unix-style paths to work. cygwin
+    lets you get away with using dos'ish paths (e.g., "f:/oo")
+    in most contexts. Using them with 'lndir' will seriously
+    confuse the user though, so under-the-hood, we convert the
+    path into something POSIX-like.
+    */
+    static char fn[MAXPATHLEN+1];
+#else
+    char *fn;
+#endif
 
     while (++av, --ac) {
-       if (strcmp(*av, "-silent") == 0)
-           silent = 1;
-       else if (strcmp(*av, "-ignorelinks") == 0)
-           ignore_links = 1;
-       else if (strcmp(*av, "--") == 0) {
-           ++av, --ac;
-           break;
-       }
-       else
-           break;
+      if (strcmp(*av, "-silent") == 0)
+         silent = 1;
+      else if (strcmp(*av, "-f") == 0)
+         force = 1;
+      else if (strcmp(*av, "-ignorelinks") == 0)
+         ignore_links = 1;
+      else if (strcmp(*av, "--") == 0) {
+         ++av, --ac;
+         break;
+      } else
+         break;
     }
 
     if (ac < 1 || ac > 2)
-       quit (1, "usage: %s [-silent] [-ignorelinks] fromdir [todir]",
+       quit (1, "usage: %s [-f] [-silent] [-ignorelinks] fromdir [todir]",
              prog_name);
 
+#ifdef __CYGWIN32__
+    cygwin_conv_to_full_posix_path(av[0], fn);
+#else
     fn = av[0];
+#endif
+
     if (ac == 2)
        tn = av[1];
     else
        tn = ".";
 
     /* to directory */
-    if (stat (tn, &ts) < 0)
+    if (stat (tn, &ts) < 0) {
+      if (force && (tn[0] != '.' || tn[1] != '\0') ) {
+         mkdir(tn, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
+      } 
+      else {
        quiterr (1, tn);
 #ifdef S_ISDIR
-    if (!(S_ISDIR(ts.st_mode)))
+        if (!(S_ISDIR(ts.st_mode)))
 #else
-    if (!(ts.st_mode & S_IFDIR))
+        if (!(ts.st_mode & S_IFDIR))
 #endif
-       quit (2, "%s: Not a directory", tn);
+          quit (2, "%s: Not a directory", tn);
+      }
+    }
     if (chdir (tn) < 0)
        quiterr (1, tn);