]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Windows: Update fs newcell and add VIOCNEWCELL2
authorJeffrey Altman <jaltman@your-file-system.com>
Thu, 3 Jun 2010 16:04:15 +0000 (12:04 -0400)
committerJeffrey Altman <jaltman@openafs.org>
Sat, 5 Jun 2010 18:33:21 +0000 (11:33 -0700)
The Windows version of "fs newcell" did not accept any parameters
and behaved quite differently from the Unix version.  Instead of
permitting new cell information to be added, the Windows version
simply forced the existing cell information to be reacquired.

This update adds a new pioctl, VIOCNEWCELL2, to support the
implementation of a Unix-style "fs newcell".  The functionality
added here differs from the Unix version in the following ways:

 1. "fs newcell" with no arguments is still accepted
    in order to maintain compatibility with prior Windows
    behavior.

 2. "fs newcell -cell <cell> -dns" instructs the cache manager
    to add the new cell but obtain the vldb server info from
    DNS.

 3. "fs newcell -cell <cell> ... -registry" instructs the cache
    manager to add the new cell and also save the cell configuration
    data in the registry for use the next time the service restarts.

 4. The -vlport and -fsport options are accepted although the
    -fsport value is currently unsupported by the cache manager.

LICENSE MIT

Change-Id: If62cc8e1c6cc8ba2defb4cd72dae8a87b4d915e0
Reviewed-on: http://gerrit.openafs.org/2080
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>
src/WINNT/afsd/NTMakefile
src/WINNT/afsd/cm_cell.c
src/WINNT/afsd/cm_cell.h
src/WINNT/afsd/cm_config.c
src/WINNT/afsd/cm_config.h
src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/cm_ioctl.h
src/WINNT/afsd/fs.c
src/WINNT/afsd/smb_iocons.h
src/WINNT/afsd/smb_ioctl.c
src/WINNT/afsd/smb_ioctl.h

index 8e92bb23c9110f1a532593dacfe39f1bc59f8ace..ba429a67d706dd0abea0399427dadf69e104ed3e 100644 (file)
@@ -204,6 +204,23 @@ MIDL_FLAGS=/app_config \
 .idl.h:
        midl $(MIDL_FLAGS) $(AFSDEV_AUXMIDLFLAGS) $<
 
+
+AFSD_SDKLIBS =\
+        netapi32.lib \
+        dnsapi.lib \
+        mpr.lib \
+        rpcrt4.lib \
+        user32.lib \
+        Dbghelp.lib \
+        strsafe.lib \
+        mpr.lib \
+        secur32.lib \
+        ole32.lib \
+        oleaut32.lib \
+        iphlpapi.lib \
+        shell32.lib \
+        shlwapi.lib
+
 ############################################################################
 # libafsconf.dll
 
@@ -214,7 +231,7 @@ CONF_DLLLIBS = \
     $(DESTDIR)\lib\afs\afsreg.lib
 
 $(CONF_DLLFILE): $(CONFOBJS) $(OUT)\libafsconf.res $(CONF_DLLLIBS)
-       $(DLLGUILINK) -def:libafsconf.def dnsapi.lib mpr.lib shell32.lib Rpcrt4.lib
+       $(DLLGUILINK) -def:libafsconf.def  $(AFSD_SDKLIBS)
         $(_VC_MANIFEST_EMBED_DLL)
        $(DLLPREP)
         $(CODESIGN_USERLAND)
@@ -400,20 +417,6 @@ $(EXEDIR)\afscpcc.exe: $(OUT)\afscpcc.obj $(OUT)\afscpcc.res $(LOGON_DLLLIBS)
 # afsd.exe
 AFSD_EXEFILE = $(EXEDIR)\afsd.exe
 
-AFSD_SDKLIBS =\
-       netapi32.lib \
-        dnsapi.lib \
-        mpr.lib \
-       rpcrt4.lib \
-       user32.lib \
-        Dbghelp.lib \
-        strsafe.lib \
-        mpr.lib \
-        secur32.lib \
-        ole32.lib \
-        oleaut32.lib \
-        iphlpapi.lib shell32.lib shlwapi.lib
-
 AFSD_EXELIBS =\
        $(DESTDIR)\lib\libosi.lib \
        $(DESTDIR)\lib\afs\mtafsvldb.lib \
index 317cd73b486754c23267e634dc288c92ef7f7d9b..3e7e516657cdf6196385bc23c701295cb3c79aa7 100644 (file)
@@ -701,3 +701,66 @@ void cm_RemoveCellFromIDHashTable(cm_cell_t *cellp)
     }
 }
 
+long
+cm_CreateCellWithInfo( char * cellname,
+                       char * linked_cellname,
+                       unsigned short vlport,
+                       afs_uint32 host_count,
+                       char *hostname[],
+                       afs_uint32 flags)
+{
+    afs_uint32 code = 0;
+    cm_cell_rock_t rock;
+    struct hostent *thp;
+    struct sockaddr_in vlSockAddr;
+    afs_uint32 i, j;
+
+    rock.cellp = cm_GetCell(cellname, CM_FLAG_CREATE | CM_FLAG_NOPROBE);
+    rock.flags = 0;
+
+    cm_FreeServerList(&rock.cellp->vlServersp, CM_FREESERVERLIST_DELETE);
+
+    if (!(flags & CM_CELLFLAG_DNS)) {
+        for (i = 0; i < host_count; i++) {
+            thp = gethostbyname(hostname[i]);
+            if (thp) {
+                int foundAddr = 0;
+                for (j=0 ; thp->h_addr_list[j]; j++) {
+                    if (thp->h_addrtype != AF_INET)
+                        continue;
+                    memcpy(&vlSockAddr.sin_addr.s_addr,
+                           thp->h_addr_list[j],
+                           sizeof(long));
+                    vlSockAddr.sin_port = htons(vlport ? vlport : 7003);
+                    vlSockAddr.sin_family = AF_INET;
+                    cm_AddCellProc(&rock, &vlSockAddr, hostname[i], CM_FLAG_NOPROBE);
+                }
+            }
+        }
+        lock_ObtainMutex(&rock.cellp->mx);
+        rock.cellp->flags &= ~CM_CELLFLAG_DNS;
+    } else if (cm_dnsEnabled) {
+        int ttl;
+
+        code = cm_SearchCellByDNS(rock.cellp->name, NULL, &ttl, cm_AddCellProc, &rock);
+        lock_ObtainMutex(&rock.cellp->mx);
+        if (code == 0) {   /* got cell from DNS */
+            rock.cellp->flags |= CM_CELLFLAG_DNS;
+            rock.cellp->timeout = time(0) + ttl;
+#ifdef DEBUG
+            fprintf(stderr, "cell %s: ttl=%d\n", rock.cellp->name, ttl);
+#endif
+        }
+    } else {
+        lock_ObtainMutex(&rock.cellp->mx);
+        rock.cellp->flags &= ~CM_CELLFLAG_DNS;
+    }
+    rock.cellp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
+    StringCbCopy(rock.cellp->linkedName, CELL_MAXNAMELEN, linked_cellname);
+    lock_ReleaseMutex(&rock.cellp->mx);
+
+    if (rock.cellp->vlServersp)
+        cm_RandomizeServer(&rock.cellp->vlServersp);
+
+    return code;
+}
index 10eed9e98e1cc5cc793e9a8924492952059e345a..a3d8931fd4563fe83c781da6ab46faba0fd9975b 100644 (file)
@@ -81,4 +81,9 @@ extern long cm_AddCellProc(void *rockp, struct sockaddr_in *addrp, char *namep,
 
 extern cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags);
 
+extern long cm_CreateCellWithInfo( char * cellname,
+                                   char * linked_cellname,
+                                   unsigned short vlport, afs_uint32 host_count,
+                                   char *hostname[], afs_uint32 flags);
+
 #endif /* __CELL_H_ENV_ */
index de175968b5924c84f60ff39de7b0ad910b53b97d..e335182972389dc1abff485a3658b94238978585 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <windows.h>
 #include <winsock2.h>
+#include <shlwapi.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -722,7 +723,113 @@ long cm_SearchCellRegistry(afs_uint32 client,
     return ((dwForceDNS || dwServers == 0) ? CM_ERROR_FORCE_DNS_LOOKUP : 0);
 }
 
-long cm_EnumerateCellRegistry(afs_uint32 client, cm_enumCellRegistryProc_t *procp, void *rockp)
+/*
+ * Following the registry schema listed above, cm_AddCellToRegistry
+ * will either create or update the registry configuration data for
+ * the specified cellname.
+ */
+long cm_AddCellToRegistry( char * cellname,
+                           char * linked_cellname,
+                           unsigned short vlport,
+                           afs_uint32 host_count,
+                           char *hostname[],
+                           afs_uint32 flags)
+{
+    HKEY hkCellServDB = 0, hkCellName = 0, hkServerName = 0;
+    DWORD dwPort, dwDisposition;
+    long code;
+    unsigned int i;
+
+    if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+                        AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
+                        0,
+                        NULL,
+                        REG_OPTION_NON_VOLATILE,
+                        KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+                        NULL,
+                        &hkCellServDB,
+                        &dwDisposition) != ERROR_SUCCESS) {
+        code = CM_ERROR_NOACCESS;
+        goto done;
+    }
+
+    /* Perform a recursive deletion of the cellname key */
+    SHDeleteKey( hkCellServDB, cellname);
+
+    if (RegCreateKeyEx( hkCellServDB,
+                        cellname,
+                        0,
+                        NULL,
+                        REG_OPTION_NON_VOLATILE,
+                        KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+                        NULL,
+                        &hkCellName,
+                        &dwDisposition) != ERROR_SUCCESS ||
+        (dwDisposition == REG_OPENED_EXISTING_KEY) ) {
+        code = CM_ERROR_NOACCESS;
+        goto done;
+    }
+
+    /* If we get here, hkCellName is a handle to an empty key */
+
+    if (linked_cellname && linked_cellname[0]) {
+        code = RegSetValueEx( hkCellName, "LinkedCell",
+                              0, REG_SZ,
+                              (BYTE *) linked_cellname, CELL_MAXNAMELEN);
+    }
+
+    if (flags & CM_CELLFLAG_DNS) {
+        DWORD dwForceDNS = 1;
+        code = RegSetValueEx( hkCellName, "ForceDNS",
+                              0, REG_DWORD,
+                              (BYTE *) &dwForceDNS, sizeof(DWORD));
+    }
+
+    for ( i = 0; i < host_count; i++ ) {
+        if (RegCreateKeyEx( hkCellName,
+                            hostname[i],
+                            0,
+                            NULL,
+                            REG_OPTION_NON_VOLATILE,
+                            KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+                            NULL,
+                            &hkServerName,
+                            &dwDisposition) != ERROR_SUCCESS ||
+             (dwDisposition == REG_OPENED_EXISTING_KEY)) {
+            code = CM_ERROR_NOACCESS;
+            goto done;
+        }
+
+        /* We have a handle to a valid server key.  Now we need
+         * to add the server to the cell */
+
+        /* First, see if there is an alternate hostname specified */
+        code = RegSetValueEx( hkServerName, "HostName",
+                              0, REG_SZ,
+                              (BYTE *) hostname[i], (DWORD)strlen(hostname[i]) + 1);
+
+        if (vlport) {
+            dwPort = vlport;
+            code = RegSetValueEx( hkServerName, "vlserver",
+                                  0, REG_DWORD,
+                                  (BYTE *) &dwPort, (DWORD)sizeof(DWORD));
+        }
+        RegCloseKey( hkServerName);
+        hkServerName = 0;
+    }
+
+  done:
+    if (hkServerName)
+        RegCloseKey(hkServerName);
+    if (hkCellName)
+        RegCloseKey(hkCellName);
+    if (hkCellServDB)
+        RegCloseKey(hkCellServDB);
+
+    return code;
+}
+
+long cm_EnumerateCellRegistry(afs_uint32 client, cm_enumCellProc_t *procp, void *rockp)
 {
     HKEY hkCellServDB = 0;
     DWORD dwSize;
index 28829077b67d2f150884e4241cead7a32f7aec36..85b2a0bbc962e2ca6bfe3233b54efddd81b232ec 100644 (file)
@@ -69,6 +69,13 @@ extern long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep);
 
 extern long cm_CloseCellFile(cm_configFile_t *filep);
 
+extern long cm_AddCellToRegistry( char * cellname,
+                                  char * linked_cellname,
+                                  unsigned short vlport,
+                                  afs_uint32 host_count,
+                                  char *hostname[],
+                                  afs_uint32 flags);
+
 extern long cm_GetCellServDB(char *cellNamep, afs_uint32 len);
 
 extern void cm_GetConfigDir(char *dir, afs_uint32 len);
index f7ffda8ddc07503b46bd227a938a328dcd93ad7f..d321ea3dffa630464eabff31cdc7f24a49c228a3 100644 (file)
@@ -10,6 +10,7 @@
 #include <afs/param.h>
 #include <afs/stds.h>
 #include <afs/cellconfig.h>
+#include <afs/afs_consts.h>
 #include <afs/ptserver.h>
 #include <ubik.h>
 
@@ -1530,6 +1531,90 @@ cm_IoctlNewCell(struct cm_ioctl *ioctlp, struct cm_user *userp)
 }
 
 /* 
+ * VIOCNEWCELL2 internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ *
+ * The pioctl data buffer consists of the following structure:
+ *
+ *  afs_uint32 flags
+ *  afs_uint32 alternative fs port
+ *  afs_uint32 alternative vl port
+ *  afs_uint32 count of vldb servers
+ *  char[]     cellname
+ *  char[]     linkedcell
+ *  n * char[] hostnames
+ */
+afs_int32
+cm_IoctlNewCell2(struct cm_ioctl *ioctlp, struct cm_user *userp)
+{
+    afs_uint32  code = 0;
+    afs_uint32  flags = 0;
+    afs_uint32  fsport = 0;
+    afs_uint32  vlport = 0;
+    afs_uint32  i, host_count = 0;
+    char *      cellname = NULL;
+    char *      linked_cellname = NULL;
+    char *tp;
+    size_t tplen;
+    afs_uint32 *lp;
+    char * hostname[AFS_MAXHOSTS];
+    size_t len;
+
+    memset(hostname, 0, sizeof(hostname));
+
+    tp = ioctlp->inDatap;
+    tplen = ioctlp->inCopied;
+    lp = (afs_uint32 *)tp;
+
+    if (tplen >= 4 * sizeof(afs_uint32)) {
+        flags = *lp++;
+        fsport = *lp++;
+        vlport = *lp++;
+        host_count = *lp++;
+        tp = (char *)lp;
+        tplen -= 4 * sizeof(afs_uint32);
+    }
+
+    if ( FAILED(StringCbLength(tp, tplen, &len)) ||
+         len + 1 > CELL_MAXNAMELEN)
+        return CM_ERROR_INVAL;
+    cellname = tp;
+    tp += len + 1;
+    tplen -= (len + 1);
+
+    if ( FAILED(StringCbLength(tp, tplen, &len)) ||
+         len + 1 > CELL_MAXNAMELEN)
+        return CM_ERROR_INVAL;
+    linked_cellname = tp;
+    tp += len + 1;
+    tplen -= (len + 1);
+
+    if (!(flags & VIOC_NEWCELL2_FLAG_USEDNS)) {
+        for ( i=0; i<host_count; i++) {
+            if ( FAILED(StringCbLength(tp, tplen, &len)) )
+                return CM_ERROR_INVAL;
+            hostname[i] = tp;
+            tp += len + 1;
+            tplen -= (len + 1);
+        }
+    }
+
+    code = cm_CreateCellWithInfo( cellname, linked_cellname,
+                                  vlport, host_count,
+                                  hostname,
+                                  (flags & VIOC_NEWCELL2_FLAG_USEDNS) ? CM_CELLFLAG_DNS : 0);
+
+    if (code == 0 && (flags & VIOC_NEWCELL2_FLAG_USEREG)) {
+        cm_AddCellToRegistry( cellname, linked_cellname,
+                              vlport, host_count,
+                              hostname,
+                              (flags & VIOC_NEWCELL2_FLAG_USEDNS) ? CM_CELLFLAG_DNS : 0);
+    }
+    return code;
+}
+
+/*
  * VIOC_GET_WS_CELL internals.
  * 
  * Assumes that pioctl path has been parsed or skipped.
index c62422ff50828c9af98cb88359ee7bb145b15a81..33a71dc7102446f844cd10d7d0bea7d2e067ca42 100644 (file)
@@ -201,6 +201,8 @@ extern afs_int32 cm_IoctlGetCell(cm_ioctl_t *ioctlp, cm_user_t *userp);
 
 extern afs_int32 cm_IoctlNewCell(cm_ioctl_t *ioctlp, cm_user_t *userp);
 
+extern afs_int32 cm_IoctlNewCell2(cm_ioctl_t *ioctlp, cm_user_t *userp);
+
 extern afs_int32 cm_IoctlGetWsCell(cm_ioctl_t *ioctlp, cm_user_t *userp);
 
 extern afs_int32 cm_IoctlSysName(cm_ioctl_t *ioctlp, cm_user_t *userp);
index d56c363725ff50d8e18438665596a96bfd894d91..c4a7edaac277202a757708e1a67db9c4b76a1bd0 100644 (file)
@@ -2974,114 +2974,182 @@ CallBackRxConnCmd(struct cmd_syndesc *as, void *arock)
 static int
 NewCellCmd(struct cmd_syndesc *as, void *arock)
 {
-#ifndef WIN32
-    afs_int32 code, linkedstate=0, size=0, *lp;
+    afs_uint32 code, linkedstate=0, size=0, count=0, *lp;
+    afs_uint32 usedns=0, useregistry=0;
     struct ViceIoctl blob;
     struct cmd_item *ti;
-    char *destEnd, *tp, *cellname=0;
-    struct hostent *thp;
-    afs_int32 fsport = 0, vlport = 0;
-    errno_t err;
+    char *tp, *cellname=0, *linked_cellname=0;
+    afs_uint32 fsport = 0, vlport = 0;
     size_t destRemaining;
 
-    memset(space, 0, AFS_MAXHOSTS * sizeof(afs_int32));
-    tp = space;
-    lp = (afs_int32 *)tp;
-    *lp++ = 0x12345678;
-    tp += sizeof(afs_int32);
-    for(ti=as->parms[1].items; ti; ti=ti->next) {
-       thp = hostutil_GetHostByName(ti->data);
-       if (!thp) {
-           fprintf(stderr,"%s: Host %s not found in host table, skipping it.\n",
-                  pn, ti->data);
-       }
-       else {
-#if _MSC_VER < 1400
-            memcpy(tp, thp->h_addr, sizeof(afs_int32));
-#else
-            err = memcpy_s(tp, sizeof(space) - (tp - space) * sizeof(char), thp->h_addr, sizeof(afs_int32));
-           if ( err ) {
-                fprintf (stderr, "memcpy_s failure on tp");
-                exit(1);
-            }
-#endif
-           tp += sizeof(afs_int32);
-       }
+    if ( !IsAdmin() ) {
+        fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n");
+        return EACCES;
     }
+
+    /* if there is no cell specified, use old Windows behavior */
+    if (as->parms[0].items == NULL) {
+        blob.in_size = 0;
+        blob.in = (char *) 0;
+        blob.out_size = AFS_PIOCTL_MAXSIZE;
+        blob.out = space;
+
+        code = pioctl_utf8((char *) 0, VIOCNEWCELL, &blob, 1);
+
+        if (code) {
+            Die(errno, (char *) 0);
+            return 1;
+        }
+
+        printf("Cell servers information refreshed\n");
+        return 0;
+    } else {
+        cellname = as->parms[0].items->data;
+    }
+
     if (as->parms[2].items) {
        /*
         * Link the cell, for the purposes of volume location, to the specified
         * cell.
         */
-       cellname = as->parms[2].items->data;
+       linked_cellname = as->parms[2].items->data;
        linkedstate = 1;
     }
-#ifdef FS_ENABLE_SERVER_DEBUG_PORTS
+
     if (as->parms[3].items) {
-       code = util_GetInt32(as->parms[3].items->data, &vlport);
+       code = util_GetInt32(as->parms[2].items->data, &vlport);
        if (code) {
            fprintf(stderr,"fs: bad integer specified for the fileserver port.\n");
            return code;
        }
     }
     if (as->parms[4].items) {
-       code = util_GetInt32(as->parms[4].items->data, &fsport);
+       code = util_GetInt32(as->parms[3].items->data, &fsport);
        if (code) {
            fprintf(stderr,"fs: bad integer specified for the vldb server port.\n");
            return code;
        }
     }
-#endif
-    tp = (char *)(space + (AFS_MAXHOSTS+1) *sizeof(afs_int32));
-    lp = (afs_int32 *)tp;    
+
+    if (as->parms[5].items) {
+        useregistry = 1;
+    }
+
+    if (as->parms[6].items) {
+        usedns = 1;
+    }
+
+    /* Count the number of hostnames */
+    for (ti=as->parms[1].items; ti && count < AFS_MAXHOSTS; ti=ti->next, count++);
+
+    if (!usedns && count == 0) {
+        fprintf( stderr, "fs: at least one vldb server must be specified.");
+        exit(1);
+    }
+
+    if (count > AFS_MAXHOSTS) {
+        fprintf( stderr, "fs: at most %u servers may be specified.", AFS_MAXHOSTS);
+        exit(1);
+    }
+
+    /*
+     * The pioctl data buffer consists of the following structure:
+     *
+     *  afs_uint32 flags
+     *  afs_uint32 alternative fs port
+     *  afs_uint32 alternative vl port
+     *  afs_uint32 count of vldb servers
+     *  char[]     cellname
+     *  char[]     linkedcell
+     *  n * char[] hostnames
+     */
+
+    memset(space, 0, sizeof(space));
+    tp = space;
+    lp = (afs_uint32 *)tp;
+
+    /* flags */
+    if (usedns)
+        *lp |= VIOC_NEWCELL2_FLAG_USEDNS;
+
+    if (useregistry)
+        *lp |= VIOC_NEWCELL2_FLAG_USEREG;
+
+    if (linkedstate)
+        *lp |= VIOC_NEWCELL2_FLAG_LINKED;
+    lp++;
+
+    /* alt fs port */
     *lp++ = fsport;
+
+    /* alt vl port */
     *lp++ = vlport;
-    *lp = linkedstate;
-    if( FAILED(StringCbCopyEx(space +  ((AFS_MAXHOSTS+4) * sizeof(afs_int32)), sizeof(space) - (AFS_MAXHOSTS+4) * sizeof(afs_int32)
-        , as->parms[0].items->data, &tp, &destRemaining, STRSAFE_FILL_ON_FAILURE))) {
-        fprintf (stderr, "var - not enough space");
+
+    /* count of server names */
+    *lp++ = count;
+
+    /* Switch back to char pointer */
+    tp = (char *)lp;
+
+    /* Add nul-terminated cellname */
+    destRemaining = sizeof(space) - (tp - space);
+    if( FAILED(StringCbCopyEx( tp,
+                               destRemaining,
+                               as->parms[0].items->data,
+                               &tp,
+                               &destRemaining,
+                               STRSAFE_FILL_ON_FAILURE))) {
+        fprintf (stderr, " not enough space for cellname");
+        exit(1);
+    }
+    /* Move beyond the terminating nul */
+    tp++;
+    destRemaining -= sizeof(char);
+
+    /* Add nul-terminated linkname */
+    if( FAILED(StringCbCopyEx( tp,
+                               destRemaining,
+                               linkedstate ? linked_cellname : "",
+                               &tp,
+                               &destRemaining,
+                               STRSAFE_FILL_ON_FAILURE))) {
+        fprintf (stderr, " not enough space for linked cellname");
         exit(1);
     }
-    tp++;   /* for null */
+    /* Move beyond the terminating nul */
+    tp++;
     destRemaining -= sizeof(char);
-    if (linkedstate) {
-        if( FAILED(StringCbCopyEx(tp, sizeof(space) - size, cellname, &destEnd, &destRemaining, STRSAFE_FILL_ON_FAILURE))) {
-            fprintf (tp, "space arr - not enough space");
+
+    /* Add the servers */
+    for (ti=as->parms[1].items; ti; ti=ti->next) {
+        if( FAILED(StringCbCopyEx( tp,
+                                   destRemaining,
+                                   ti->data,
+                                   &tp,
+                                   &destRemaining,
+                                   STRSAFE_FILL_ON_FAILURE))) {
+            fprintf (stderr, " not enough space for server %s", ti->data);
             exit(1);
-       }
-        size += destEnd - tp + 1;
+        }
+        /* Move beyond the terminating nul */
+        tp++;
+        destRemaining -= sizeof(char);
     }
-    blob.in_size = size;
+
+    blob.in_size = (tp - space);
     blob.in = space;
     blob.out_size = 0;
-    code = pioctl_utf8(0, VIOCNEWCELL, &blob, 1);
-    if (code < 0)
-       Die(errno, 0);
-    return 0;
-#else /* WIN32 */
-    afs_int32 code;
-    struct ViceIoctl blob;
-    
-    if ( !IsAdmin() ) {
-        fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n");
-        return EACCES;
-    }
-
-    blob.in_size = 0;
-    blob.in = (char *) 0;
-    blob.out_size = AFS_PIOCTL_MAXSIZE;
     blob.out = space;
-
-    code = pioctl_utf8((char *) 0, VIOCNEWCELL, &blob, 1);
+    code = pioctl_utf8(NULL, VIOCNEWCELL2, &blob, 1);
 
     if (code) {
-        Die(errno, (char *) 0);
+        Die(errno, as->parms[0].items->data);
         return 1;
     }
     
-    printf("Cell servers information refreshed\n");
+    printf("Cell servers information for %s added or updated.\n",
+           as->parms[0].items->data);
     return 0;
-#endif /* WIN32 */
 }
 
 #ifndef WIN32
@@ -5694,12 +5762,10 @@ int wmain(int argc, wchar_t **wargv)
     cmd_CreateAlias(ts, "sq");
 
     ts = cmd_CreateSyntax("newcell", NewCellCmd, NULL, "configure new cell");
-#ifndef WIN32
-    cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "cell name");
-    cmd_AddParm(ts, "-servers", CMD_LIST, CMD_REQUIRED, "primary servers");
+    cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_OPTIONAL, "cell name");
+    cmd_AddParm(ts, "-servers", CMD_LIST, CMD_OPTIONAL, "primary servers");
     cmd_AddParm(ts, "-linkedcell", CMD_SINGLE, CMD_OPTIONAL, "linked cell name");
 
-#ifdef FS_ENABLE_SERVER_DEBUG_PORTS
     /*
      * Turn this on only if you wish to be able to talk to a server which is listening
      * on alternative ports. This is not intended for general use and may not be
@@ -5708,8 +5774,10 @@ int wmain(int argc, wchar_t **wargv)
      */
     cmd_AddParm(ts, "-fsport", CMD_SINGLE, CMD_OPTIONAL, "cell's fileserver port");
     cmd_AddParm(ts, "-vlport", CMD_SINGLE, CMD_OPTIONAL, "cell's vldb server port");
-#endif
+    cmd_AddParm(ts, "-registry", CMD_FLAG, CMD_OPTIONAL, "add cell info to registry cellservdb");
+    cmd_AddParm(ts, "-dns",    CMD_FLAG, CMD_OPTIONAL,   "force use of dns");
 
+#ifndef WIN32
     ts = cmd_CreateSyntax("newalias", NewAliasCmd, NULL,
                          "configure new cell alias");
     cmd_AddParm(ts, "-alias", CMD_SINGLE, 0, "alias name");
index 9ecb13970efdbd71c0cf34e544278673ea0953f2..ada88341693459288550cbe439adb998f4fd9e6d 100644 (file)
@@ -98,9 +98,14 @@ struct sbstruct {
 #define VIOC_SETOWNER                   0x34
 #define VIOC_SETGROUP                   0x35
 #define VIOC_FS_CMD                     0x36
+#define VIOCNEWCELL2                    0x37
 
 #define VIOC_VOLSTAT_TEST               0x3F
 
+#define VIOC_NEWCELL2_FLAG_LINKED       0x1
+#define VIOC_NEWCELL2_FLAG_USEDNS       0x2
+#define VIOC_NEWCELL2_FLAG_USEREG       0x4
+
 /* magic file name for ioctl opens */
 #define CM_IOCTL_FILENAME      "\\_._AFS_IOCTL_._"     /* double backslashes for C compiler */
 #define CM_IOCTL_FILENAME_NOSLASH "_._AFS_IOCTL_._"
index b11268a8fbc2bc3aed9e98c7780ada93ffff02d6..55b6bf9f319fab7d4f3b9dbad83afbca084704c0 100644 (file)
@@ -89,6 +89,7 @@ smb_InitIoctl(void)
     smb_ioctlProcsp[VIOC_UNICODECTL] = smb_IoctlUnicodeControl;
     smb_ioctlProcsp[VIOC_SETOWNER] = smb_IoctlSetOwner;
     smb_ioctlProcsp[VIOC_SETGROUP] = smb_IoctlSetGroup;
+    smb_ioctlProcsp[VIOCNEWCELL2] = smb_IoctlNewCell2;
 }       
 
 /* called to make a fid structure into an IOCTL fid structure */
@@ -1554,6 +1555,14 @@ smb_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
+smb_IoctlNewCell2(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+    cm_SkipIoctlPath(&ioctlp->ioctl);
+
+    return cm_IoctlNewCell2(&ioctlp->ioctl, userp);
+}
+
+afs_int32
 smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
index 033533f60bd8a24840e97a5d678d93830adb77b1..ba136d31f706295c6af1224239f7bde2de6ecea9 100644 (file)
@@ -128,6 +128,8 @@ extern afs_int32 smb_IoctlGetCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
 
 extern afs_int32 smb_IoctlNewCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
 
+extern afs_int32 smb_IoctlNewCell2(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
 extern afs_int32 smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
 
 extern afs_int32 smb_IoctlSysName(smb_ioctl_t *ioctlp, cm_user_t *userp);