home *** CD-ROM | disk | FTP | other *** search
- /*
- * FLATTOHEIRARCHICAL.C
- *
- * FLATTOHEIRARCHICAL FLAT/HEIR
- *
- * This program will convert between the two types of news heirarchies.
- * You can safely ^C this program and restart it at anytime. Note that
- * while simply renaming directories is much, much, much faster, I
- * decided to design the program this way to give it the capability
- * to 'pick up the pieces' when people screw up their own attempts to
- * convert.
- */
-
- #include <exec/types.h>
- #include <exec/nodes.h>
- #include <exec/lists.h>
- #include <exec/memory.h>
-
- extern int mkdir(const char *);
- extern int rmdir(const char *);
-
- #include <dos/dostags.h>
- #include <dos/exall.h>
-
- #include <clib/dos_protos.h>
- #include <clib/exec_protos.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <config.h>
- #include <version.h>
- #include <lib_protos.h>
- #include <owndevunit.h>
-
- typedef struct FileInfoBlock FileInfoBlock;
- typedef struct Node Node;
- typedef struct List List;
-
- void myexit(void);
- void ConvertToFlat(char *);
- void ConvertToHeir(char *);
-
- void mksubdirs(char *);
- int ScanDirTree(List *, char *, short);
- int RenameScan(char *, char *);
-
- struct Library *OwnDevUnitBase;
-
- char ScanPath[1024];
- char DirPath[1024];
-
- IDENT(".02");
-
- int main(int ac, char **av)
- {
- if (ac == 1) {
- puts("FLATTOHEIRARCHICAL H[ier] - convert to a heirarchical");
- puts("FLATTOHEIRARCHICAL F[lat] - convert back to a flat");
- exit(0);
- }
-
- atexit (myexit);
- if ((OwnDevUnitBase = OpenLibrary ((UBYTE *) ODU_NAME, 0)) == NULL) {
- printf ("Unable to open %s\n", ODU_NAME);
- exit (20);
- }
-
- strcpy(DirPath, GetConfigDir(UUNEWS));
-
- switch(av[1][0]) {
- case 'f':
- case 'F':
- ConvertToFlat(DirPath);
- break;
- case 'h':
- case 'H':
- ConvertToHeir(DirPath);
- break;
- default:
- puts("Bad option");
- exit(10);
- }
- }
-
- void
- myexit()
- {
- UnLockFiles();
-
- if (OwnDevUnitBase) {
- CloseLibrary(OwnDevUnitBase);
- OwnDevUnitBase = NULL;
- }
- }
-
- /*
- * Convert a heirarchical directory structure into a flat structure
- */
-
- void
- ConvertToFlat(dir)
- char *dir;
- {
- List list;
- Node *node;
- short len = strlen(dir);
-
- /*
- * Obtain list of directories, e.g.:
- * uunews:
- * uunews:alt
- * uunews:alt/sys
- * uunews:comp
- * ...
- *
- * Scan backwords to 'back out' of the tree
- */
-
- NewList(&list);
- if (ScanDirTree(&list, dir, 1) < 0) {
- printf("Unable to scan %s\n", dir);
- return;
- }
-
- /*
- * Convert to a flat namespace by replacing all occurances of '/'
- * after the first len bytes to '.'
- */
-
- while (node = RemTail(&list)) {
- char *ptr;
-
- strcpy(dir, node->ln_Name);
- while (ptr = strchr(dir + len + 1, '/'))
- *ptr = '.';
-
- /*
- * If not the same path then create the flat directory (could
- * already exist, ignore return code) and rename all files
- * into it, then delete the heirarchical dir.
- */
-
- printf("%-15s TO %-15s\n", node->ln_Name, dir);
- if (strcmp(node->ln_Name, dir) != 0) {
- mkdir(dir);
- if (RenameScan(node->ln_Name, dir) == 0)
- rmdir(node->ln_Name);
- else
- printf("Unable to move all files from %s\n", node->ln_Name);
- } else {
- /*
- * remove directory if empty (ignore error code, dir is not
- * necessarily empty)
- */
- rmdir(dir);
- }
- free(node);
- }
- }
-
- /*
- * Convert a flat structure to a heirarchical structure
- */
-
- void
- ConvertToHeir(dir)
- char *dir;
- {
- List list;
- Node *node;
- short len = strlen(dir);
-
- /*
- * Obtain list of directories, e.g.:
- * uunews:
- * uunews:alt
- * uunews:alt.sys.amiga
- * uunews:comp
- * ...
- *
- * Scan sequence does not matter, order can be anything.
- */
-
- NewList(&list);
- if (ScanDirTree(&list, dir, 1) < 0) {
- printf("Unable to scan %s\n", dir);
- return;
- }
-
- /*
- * Convert to a heirarchical namespace by replacing all occurances of '.'
- * after the first len bytes to '/' and creating inbetween directories
- * as necessary.
- */
-
- while (node = RemTail(&list)) {
- char *ptr;
-
- strcpy(dir, node->ln_Name);
- while (ptr = strchr(dir + len + 1, '.'))
- *ptr = '/';
-
- /*
- * If not the same path then create the heir directory and
- * rename all files into it, then delete the original flat
- * directory.
- */
-
- printf("%-15s TO %-15s\n", node->ln_Name, dir);
-
- if (strcmp(node->ln_Name, dir) != 0) {
- mksubdirs(dir);
- if (RenameScan(node->ln_Name, dir) == 0)
- rmdir(node->ln_Name);
- else
- printf("Unable to move all files from %s\n", node->ln_Name);
- } else {
- /*
- * remove directory if empty (ignore error code, dir is not
- * necessarily empty)
- */
- rmdir(dir);
- }
- free(node);
- }
- }
-
- void
- mksubdirs(char *dir)
- {
- BPTR lock;
- char *ptr;
-
- if (lock = Lock ((UBYTE *) dir, SHARED_LOCK)) {
- UnLock (lock);
- return;
- }
- if (ptr = strrchr(dir, '/')) {
- *ptr = 0;
- mksubdirs(dir);
- *ptr = '/';
- }
- mkdir(dir);
- }
-
- int
- ScanDirTree (List *list, char *dir, short dirOnly)
- {
- BPTR lock;
- #if !defined (__GNUC__)
- __aligned
- #endif
- FileInfoBlock fib;
- int r = -1;
- short len = strlen (dir);
-
- if (lock = Lock ((UBYTE *) dir, SHARED_LOCK)) {
- r = 0;
- if (Examine (lock, &fib)) {
- while (ExNext (lock, &fib)) {
- Node *node;
-
- if (len && dir[len-1] != ':')
- strcat(dir, "/");
- strcat(dir, fib.fib_FileName);
-
- if ((fib.fib_DirEntryType > 0 && dirOnly) || (fib.fib_DirEntryType < 0 && dirOnly == 0)) {
- node = malloc(sizeof(Node) + strlen(dir) + 1);
- node->ln_Name = (char *)(node + 1);
- strcpy(node->ln_Name, dir);
- AddTail (list, node);
- }
- if (fib.fib_DirEntryType > 0)
- ScanDirTree(list, dir, dirOnly);
- dir[len] = 0;
- }
- }
- UnLock(lock);
- }
- return(r);
- }
-
- /*
- *
- *
- *
- */
-
- int
- RenameScan (char *sdir, char *ddir)
- {
- List list;
- short slen = strlen(sdir);
- short dlen = strlen(ddir);
- int r = -1;
-
- NewList(&list);
-
- strcpy(ScanPath, sdir);
- if (ScanDirTree(&list, ScanPath, 0) == 0) {
- Node *node;
-
- r = 0;
- while (node = RemHead(&list)) {
- /*printf("node %08lx name %s\n", node, node->ln_Name);*/
-
- strcpy(ddir + dlen, node->ln_Name + slen);
- if (rename(node->ln_Name, ddir) < 0) {
- r = -1;
- printf("Unable to rename %s to %s\n", node->ln_Name, ddir);
- }
- free(node);
- }
- ddir[dlen] = 0;
- }
- return(r);
- }
-
-