#include <malloc.h>
#include <string.h>
+#include <WINNT/afsreg.h>
+#include "afsd.h"
#include <rx/rx.h>
-#include "afsd.h"
#ifdef AFS_FREELANCE_CLIENT
#include "cm_freelance.h"
#include "stdio.h"
int cm_fakeDirSize;
int cm_fakeDirCallback=0;
int cm_fakeGettingCallback=0;
-int cm_fakeDirVersion = 0x8;
cm_localMountPoint_t* cm_localMountPoints;
osi_mutex_t cm_Freelance_Lock;
int cm_localMountPointChangeFlag = 0;
-int cm_freelanceEnabled = 0;
+int cm_freelanceEnabled = 1;
time_t FakeFreelanceModTime = 0x3b49f6e2;
+static int freelance_ShutdownFlag = 0;
+#if !defined(DJGPP)
+static HANDLE hFreelanceChangeEvent = 0;
+static HANDLE hFreelanceSymlinkChangeEvent = 0;
+#endif
+
void cm_InitFakeRootDir();
#if !defined(DJGPP)
void cm_FreelanceChangeNotifier(void * parmp) {
- HANDLE hFreelanceChangeEvent = 0;
HKEY hkFreelance = 0;
if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
- "SOFTWARE\\OpenAFS\\Client\\Freelance",
+ AFSREG_CLT_OPENAFS_SUBKEY "\\Freelance",
0,
KEY_NOTIFY,
&hkFreelance) == ERROR_SUCCESS) {
) != ERROR_SUCCESS) {
RegCloseKey(hkFreelance);
CloseHandle(hFreelanceChangeEvent);
+ hFreelanceChangeEvent = 0;
return;
}
if (WaitForSingleObject(hFreelanceChangeEvent, INFINITE) == WAIT_OBJECT_0)
{
+ if (freelance_ShutdownFlag == 1) {
+ RegCloseKey(hkFreelance);
+ CloseHandle(hFreelanceChangeEvent);
+ hFreelanceChangeEvent = 0;
+ return;
+ }
+ cm_noteLocalMountPointChange();
+ }
+ }
+}
+
+void cm_FreelanceSymlinkChangeNotifier(void * parmp) {
+ HKEY hkFreelance = 0;
+
+ if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_OPENAFS_SUBKEY "\\Freelance\\Symlinks",
+ 0,
+ KEY_NOTIFY,
+ &hkFreelance) == ERROR_SUCCESS) {
+
+ hFreelanceSymlinkChangeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (hFreelanceSymlinkChangeEvent == NULL) {
+ RegCloseKey(hkFreelance);
+ return;
+ }
+ }
+
+ while ( TRUE ) {
+ /* check hFreelanceSymlinkChangeEvent to see if it is set.
+ * if so, call cm_noteLocalMountPointSymlinkChange()
+ */
+ if (RegNotifyChangeKeyValue( hkFreelance, /* hKey */
+ FALSE, /* bWatchSubtree */
+ REG_NOTIFY_CHANGE_LAST_SET, /* dwNotifyFilter */
+ hFreelanceSymlinkChangeEvent, /* hEvent */
+ TRUE /* fAsynchronous */
+ ) != ERROR_SUCCESS) {
+ RegCloseKey(hkFreelance);
+ CloseHandle(hFreelanceSymlinkChangeEvent);
+ hFreelanceSymlinkChangeEvent = 0;
+ return;
+ }
+
+ if (WaitForSingleObject(hFreelanceSymlinkChangeEvent, INFINITE) == WAIT_OBJECT_0)
+ {
+ if (freelance_ShutdownFlag == 1) {
+ RegCloseKey(hkFreelance);
+ CloseHandle(hFreelanceSymlinkChangeEvent);
+ hFreelanceSymlinkChangeEvent = 0;
+ return;
+ }
cm_noteLocalMountPointChange();
}
}
}
#endif
+void
+cm_FreelanceShutdown(void)
+{
+ freelance_ShutdownFlag = 1;
+#if !defined(DJGPP)
+ if (hFreelanceChangeEvent != 0)
+ thrd_SetEvent(hFreelanceChangeEvent);
+ if (hFreelanceSymlinkChangeEvent != 0)
+ thrd_SetEvent(hFreelanceSymlinkChangeEvent);
+#endif
+}
+
void cm_InitFreelance() {
#if !defined(DJGPP)
thread_t phandle;
lock_InitializeMutex(&cm_Freelance_Lock, "Freelance Lock");
+ // make sure we sync the data version to the cached root scache_t
+ if (cm_data.rootSCachep && cm_data.rootSCachep->fid.cell == AFS_FAKE_ROOT_CELL_ID)
+ cm_data.fakeDirVersion = cm_data.rootSCachep->dataVersion;
+
// yj: first we make a call to cm_initLocalMountPoints
- // to read all the local mount points from an ini file
+ // to read all the local mount points from the registry
cm_InitLocalMountPoints();
// then we make a call to InitFakeRootDir to create
/* Start the registry monitor */
phandle = thrd_Create(NULL, 65536, (ThreadFunc) cm_FreelanceChangeNotifier,
NULL, 0, &lpid, "cm_FreelanceChangeNotifier");
- osi_assert(phandle != NULL);
+ osi_assertx(phandle != NULL, "cm_FreelanceChangeNotifier thread create failure");
+ thrd_CloseHandle(phandle);
+
+ phandle = thrd_Create(NULL, 65536, (ThreadFunc) cm_FreelanceSymlinkChangeNotifier,
+ NULL, 0, &lpid, "cm_FreelanceSymlinkChangeNotifier");
+ osi_assertx(phandle != NULL, "cm_FreelanceSymlinkChangeNotifier thread create failure");
thrd_CloseHandle(phandle);
#endif
}
/* yj: Initialization of the fake root directory */
/* to be called while holding freelance lock unless during init. */
void cm_InitFakeRootDir() {
-
int i, t1, t2;
char* currentPos;
int noChunks;
/* Reserve 2 directory chunks for "." and ".." */
curChunk += 2;
- while (curDirEntry!=cm_noLocalMountPoints) {
+ while (curDirEntry<cm_noLocalMountPoints) {
sizeOfCurEntry = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0);
if ((curChunk + sizeOfCurEntry >= CPP) ||
(curDirEntryInPage + 1 >= CM_DIR_EPP)) {
// 2. we have less than CM_DIR_EPP entries in page 0
// 3. we're not out of chunks in page 0
- while( (curDirEntry!=cm_noLocalMountPoints) &&
+ while( (curDirEntry<cm_noLocalMountPoints) &&
(curDirEntryInPage < CM_DIR_EPP) &&
(curChunk + cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0) <= CPP))
{
curPage++;
// ok, page 0's done. Move on to the next page.
- while (curDirEntry!=cm_noLocalMountPoints) {
+ while (curDirEntry<cm_noLocalMountPoints) {
// setup a new page
curChunk = 1; // the zeroth chunk is reserved for page header
curDirEntryInPage = 0;
fakePageHeader.tag = htons(1234);
// while we're on the same page...
- while ( (curDirEntry!=cm_noLocalMountPoints) &&
+ while ( (curDirEntry<cm_noLocalMountPoints) &&
(curDirEntryInPage < CM_DIR_EPP) &&
(curChunk + cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0) <= CPP))
{
int cm_FakeRootFid(cm_fid_t *fidp)
{
fidp->cell = AFS_FAKE_ROOT_CELL_ID; /* root cell */
- fidp->volume = AFS_FAKE_ROOT_VOL_ID; /* root.afs ? */
+ fidp->volume = AFS_FAKE_ROOT_VOL_ID; /* root.afs ? */
fidp->vnode = 0x1;
fidp->unique = 0x1;
return 0;
/* called directly from ioctl */
/* called while not holding freelance lock */
-int cm_noteLocalMountPointChange() {
+int cm_noteLocalMountPointChange(void) {
lock_ObtainMutex(&cm_Freelance_Lock);
- cm_fakeDirVersion++;
+ cm_data.fakeDirVersion++;
cm_localMountPointChangeFlag = 1;
lock_ReleaseMutex(&cm_Freelance_Lock);
return 1;
lock_ObtainMutex(&cm_Freelance_Lock); /* always scache then freelance lock */
for (i=0; i<cm_noLocalMountPoints; i++) {
hash = CM_SCACHE_HASH(&aFid);
- for (scp=cm_hashTablep[hash]; scp; scp=scp->nextp) {
+ for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) {
if (scp->fid.volume == aFid.volume &&
scp->fid.vnode == aFid.vnode &&
scp->fid.unique == aFid.unique
) {
// mark the scp to be reused
+ cm_HoldSCacheNoLock(scp);
lock_ReleaseWrite(&cm_scacheLock);
lock_ObtainMutex(&scp->mx);
cm_DiscardSCache(scp);
lock_ReleaseMutex(&scp->mx);
cm_CallbackNotifyChange(scp);
lock_ObtainWrite(&cm_scacheLock);
- scp->refCount--;
+ cm_ReleaseSCacheNoLock(scp);
// take the scp out of the hash
- lscpp = &cm_hashTablep[hash];
- for (tscp=*lscpp; tscp; lscpp = &tscp->nextp, tscp = *lscpp) {
- if (tscp == scp) break;
+ for (lscpp = &cm_data.scacheHashTablep[hash], tscp = cm_data.scacheHashTablep[hash];
+ tscp;
+ lscpp = &tscp->nextp, tscp = tscp->nextp) {
+ if (tscp == scp) {
+ *lscpp = scp->nextp;
+ lock_ObtainMutex(&scp->mx);
+ scp->flags &= ~CM_SCACHEFLAG_INHASH;
+ lock_ReleaseMutex(&scp->mx);
+ break;
+ }
}
- *lscpp = scp->nextp;
- scp->flags &= ~CM_SCACHEFLAG_INHASH;
}
}
aFid.vnode = aFid.vnode + 1;
}
-// yj: open up the ini file and read all the local mount
+// yj: open up the registry and read all the local mount
// points that are stored there. Part of the initialization
// process for the freelance client.
/* to be called while holding freelance lock unless during init. */
long code;
char rootCellName[256];
#if !defined(DJGPP)
- HKEY hkFreelance = 0;
+ HKEY hkFreelance = 0, hkFreelanceSymlinks = 0;
DWORD dwType, dwSize;
- DWORD dwMountPoints;
+ DWORD dwMountPoints = 0;
DWORD dwIndex;
+ DWORD dwSymlinks = 0;
FILETIME ftLastWriteTime;
- afs_uint32 unixTime;
#endif
#if !defined(DJGPP)
if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
- "SOFTWARE\\OpenAFS\\Client\\Freelance",
- 0,
- KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
- &hkFreelance) == ERROR_SUCCESS) {
+ AFSREG_CLT_OPENAFS_SUBKEY "\\Freelance",
+ 0,
+ KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+ &hkFreelance) == ERROR_SUCCESS) {
RegQueryInfoKey( hkFreelance,
NULL, /* lpClass */
smb_UnixTimeFromLargeSearchTime(&FakeFreelanceModTime, &ftLastWriteTime);
if ( dwMountPoints == 0 ) {
- sprintf(line,"%s#%s:root.cell.\n",rootCellName,rootCellName);
- dwType = REG_SZ;
- dwSize = strlen(line) + 1;
- RegSetValueEx( hkFreelance, "0", 0, dwType, line, dwSize);
- sprintf(line,".%s%%%s:root.cell.\n",rootCellName,rootCellName);
- dwSize = strlen(line) + 1;
- RegSetValueEx( hkFreelance, "1", 0, dwType, line, dwSize);
- dwMountPoints = 2;
+ rootCellName[0] = '.';
+ code = cm_GetRootCellName(&rootCellName[1]);
+ if (code == 0) {
+ cm_FreelanceAddMount(&rootCellName[1], &rootCellName[1], "root.cell.", 0, NULL);
+ cm_FreelanceAddMount(rootCellName, &rootCellName[1], "root.cell.", 1, NULL);
+ cm_FreelanceAddMount(".root", &rootCellName[1], "root.afs.", 1, NULL);
+ dwMountPoints = 3;
+ }
+ }
+
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_OPENAFS_SUBKEY "\\Freelance\\Symlinks",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+ NULL,
+ &hkFreelanceSymlinks,
+ NULL) == ERROR_SUCCESS) {
+
+ RegQueryInfoKey( hkFreelanceSymlinks,
+ NULL, /* lpClass */
+ NULL, /* lpcClass */
+ NULL, /* lpReserved */
+ NULL, /* lpcSubKeys */
+ NULL, /* lpcMaxSubKeyLen */
+ NULL, /* lpcMaxClassLen */
+ &dwSymlinks, /* lpcValues */
+ NULL, /* lpcMaxValueNameLen */
+ NULL, /* lpcMaxValueLen */
+ NULL, /* lpcbSecurityDescriptor */
+ NULL /* lpftLastWriteTime */
+ );
}
// get the number of entries there are from the first line
// that we read
- cm_noLocalMountPoints = dwMountPoints;
+ cm_noLocalMountPoints = dwMountPoints + dwSymlinks;
// create space to store the local mount points
cm_localMountPoints = malloc(sizeof(cm_localMountPoint_t) * cm_noLocalMountPoints);
TCHAR szValueName[16];
DWORD dwValueSize = 16;
dwSize = sizeof(line);
- RegEnumValue( hkFreelance, dwIndex, szValueName, &dwValueSize, NULL,
- &dwType, line, &dwSize);
+ if (RegEnumValue( hkFreelance, dwIndex, szValueName, &dwValueSize, NULL,
+ &dwType, line, &dwSize))
+ {
+ afsi_log("RegEnumValue(hkFreelance) failed");
+ cm_noLocalMountPoints--;
+ continue;
+ }
+
+ afsi_log("Mountpoint[%d] = %s",dwIndex, line);
/* find the trailing dot; null terminate after it */
t2 = strrchr(line, '.');
if (t2)
*(t2+1) = '\0';
+ for ( t=line;*t;t++ ) {
+ if ( !isprint(*t) ) {
+ afsi_log("error occurred while parsing mountpoint entry [%d]: non-printable character", dwIndex);
+ fprintf(stderr, "error occurred while parsing mountpoint entry [%d]: non-printable character", dwIndex);
+ cm_noLocalMountPoints--;
+ continue;
+ }
+ }
+
// line is not empty, so let's parse it
t = strchr(line, '#');
if (!t)
t = strchr(line, '%');
// make sure that there is a '#' or '%' separator in the line
if (!t) {
- afsi_log("error occurred while parsing entry in %s: no # or %% separator in line %d", AFS_FREELANCE_INI, dwIndex);
- fprintf(stderr, "error occurred while parsing entry in afs_freelance.ini: no # or %% separator in line %d", dwIndex);
+ afsi_log("error occurred while parsing mountpoint entry [%d]: no # or %% separator", dwIndex);
+ fprintf(stderr, "error occurred while parsing mountpoint entry [%d]: no # or %% separator", dwIndex);
cm_noLocalMountPoints--;
continue;
}
+
+ aLocalMountPoint->fileType = CM_SCACHETYPE_MOUNTPOINT;
aLocalMountPoint->namep=malloc(t-line+1);
strncpy(aLocalMountPoint->namep, line, t-line);
aLocalMountPoint->namep[t-line] = '\0';
- /* copy the mount point string without the trailing dot */
+ /* copy the mount point string */
aLocalMountPoint->mountPointStringp=malloc(strlen(t));
- strncpy(aLocalMountPoint->mountPointStringp, t, strlen(t)-1);
- aLocalMountPoint->mountPointStringp[strlen(t)-1] = '\0';
+ strncpy(aLocalMountPoint->mountPointStringp, t, strlen(t)-1);
+ aLocalMountPoint->mountPointStringp[strlen(t)-1] = '\0';
osi_Log2(afsd_logp,"found mount point: name %s, string %s",
osi_LogSaveString(afsd_logp,aLocalMountPoint->namep),
aLocalMountPoint++;
}
+ for ( dwIndex = 0 ; dwIndex < dwSymlinks; dwIndex++ ) {
+ TCHAR szValueName[16];
+ DWORD dwValueSize = 16;
+ dwSize = sizeof(line);
+ if (RegEnumValue( hkFreelanceSymlinks, dwIndex, szValueName, &dwValueSize, NULL,
+ &dwType, line, &dwSize))
+ {
+ afsi_log("RegEnumValue(hkFreelanceSymlinks) failed");
+ cm_noLocalMountPoints--;
+ continue;
+ }
+
+ afsi_log("Symlink[%d] = %s",dwIndex, line);
+
+ /* find the trailing dot; null terminate after it */
+ t2 = strrchr(line, '.');
+ if (t2)
+ *(t2+1) = '\0';
+
+ for ( t=line;*t;t++ ) {
+ if ( !isprint(*t) ) {
+ afsi_log("error occurred while parsing symlink entry [%d]: non-printable character", dwIndex);
+ fprintf(stderr, "error occurred while parsing symlink entry [%d]: non-printable character", dwIndex);
+ cm_noLocalMountPoints--;
+ continue;
+ }
+ }
+
+ // line is not empty, so let's parse it
+ t = strchr(line, ':');
+
+ // make sure that there is a ':' separator in the line
+ if (!t) {
+ afsi_log("error occurred while parsing symlink entry [%d]: no ':' separator", dwIndex);
+ fprintf(stderr, "error occurred while parsing symlink entry [%d]: no ':' separator", dwIndex);
+ cm_noLocalMountPoints--;
+ continue;
+ }
+
+ aLocalMountPoint->fileType = CM_SCACHETYPE_SYMLINK;
+ aLocalMountPoint->namep=malloc(t-line+1);
+ strncpy(aLocalMountPoint->namep, line, t-line);
+ aLocalMountPoint->namep[t-line] = '\0';
+
+ /* copy the symlink string */
+ aLocalMountPoint->mountPointStringp=malloc(strlen(t)-1);
+ strncpy(aLocalMountPoint->mountPointStringp, t+1, strlen(t)-2);
+ aLocalMountPoint->mountPointStringp[strlen(t)-2] = '\0';
+
+ osi_Log2(afsd_logp,"found symlink: name %s, string %s",
+ osi_LogSaveString(afsd_logp,aLocalMountPoint->namep),
+ osi_LogSaveString(afsd_logp,aLocalMountPoint->mountPointStringp));
+
+ aLocalMountPoint++;
+ }
+
+ if ( hkFreelanceSymlinks )
+ RegCloseKey( hkFreelanceSymlinks );
RegCloseKey(hkFreelance);
return 0;
}
strcat(hdir, AFS_FREELANCE_INI);
// open the ini file for reading
fp = fopen(hdir, "r");
-
- // if we fail to open the file, create an empty one
if (!fp) {
- fp = fopen(hdir, "w");
- code = cm_GetRootCellName(rootCellName);
- if (code == 0) {
- fputs("1\n", fp);
- fprintf(fp,"%s#%s:root.cell.\n",rootCellName,rootCellName);
- fprintf(fp,".%s%%%s:root.cell.\n",rootCellName,rootCellName);
- fclose(fp);
- fp = fopen(hdir, "r");
- } else {
- fputs("0\n", fp);
- fclose(fp);
- return 0; /* success */
- }
+ /* look in the Windows directory where we used to store the file */
+ GetWindowsDirectory(hdir, sizeof(hdir));
+ strcat(hdir,"\\");
+ strcat(hdir, AFS_FREELANCE_INI);
+ fp = fopen(hdir, "r");
}
- // we successfully opened the file
- osi_Log0(afsd_logp,"opened afs_freelance.ini");
-
#if !defined(DJGPP)
RegCreateKeyEx( HKEY_LOCAL_MACHINE,
- "SOFTWARE\\OpenAFS\\Client\\Freelance",
+ AFSREG_CLT_OPENAFS_SUBKEY "\\Freelance",
0,
NULL,
REG_OPTION_NON_VOLATILE,
dwIndex = 0;
#endif
+ if (!fp) {
+#if !defined(DJGPP)
+ RegCloseKey(hkFreelance);
+#endif
+ rootCellName[0] = '.';
+ code = cm_GetRootCellName(&rootCellName[1]);
+ if (code == 0) {
+ cm_FreelanceAddMount(&rootCellName[1], &rootCellName[1], "root.cell.", 0, NULL);
+ cm_FreelanceAddMount(rootCellName, &rootCellName[1], "root.cell.", 1, NULL);
+ cm_FreelanceAddMount(".root", &rootCellName[1], "root.afs.", 1, NULL);
+ }
+ return 0;
+ }
+
+ // we successfully opened the file
+ osi_Log0(afsd_logp,"opened afs_freelance.ini");
+
// now we read the first line to see how many entries
// there are
fgets(line, sizeof(line), fp);
// that we read
cm_noLocalMountPoints = atoi(line);
- // create space to store the local mount points
- cm_localMountPoints = malloc(sizeof(cm_localMountPoint_t) * cm_noLocalMountPoints);
- aLocalMountPoint = cm_localMountPoints;
+ if (cm_noLocalMountPoints > 0) {
+ // create space to store the local mount points
+ cm_localMountPoints = malloc(sizeof(cm_localMountPoint_t) * cm_noLocalMountPoints);
+ aLocalMountPoint = cm_localMountPoints;
+ }
// now we read n lines and parse them into local mount points
// where n is the number of local mount points there are, as
return -1;
}
+ /* find the trailing dot; null terminate after it */
+ t2 = strrchr(line, '.');
+ if (t2)
+ *(t2+1) = '\0';
+
#if !defined(DJGPP)
if ( hkFreelance ) {
char szIndex[16];
/* we are migrating to the registry */
sprintf(szIndex,"%d",dwIndex++);
dwType = REG_SZ;
- dwSize = strlen(line) + 1;
+ dwSize = (DWORD)strlen(line) + 1;
RegSetValueEx( hkFreelance, szIndex, 0, dwType, line, dwSize);
}
#endif
*(aLocalMountPoint->namep + (t-line)) = 0;
aLocalMountPoint->mountPointStringp=malloc(strlen(line) - (t-line) + 1);
- memcpy(aLocalMountPoint->mountPointStringp, t, strlen(line)-(t-line)-2);
- *(aLocalMountPoint->mountPointStringp + (strlen(line)-(t-line)-2)) = 0;
+ memcpy(aLocalMountPoint->mountPointStringp, t, strlen(line)-(t-line)-1);
+ *(aLocalMountPoint->mountPointStringp + (strlen(line)-(t-line)-1)) = 0;
osi_Log2(afsd_logp,"found mount point: name %s, string %s",
aLocalMountPoint->namep,
return cm_noLocalMountPoints;
}
-cm_localMountPoint_t* cm_getLocalMountPoint(int vnode) {
- return 0;
+#if !defined(DJGPP)
+long cm_FreelanceMountPointExists(char * filename, int prefix_ok)
+{
+ char* cp;
+ char line[512];
+ char shortname[200];
+ int found = 0;
+ HKEY hkFreelance = 0;
+ DWORD dwType, dwSize;
+ DWORD dwMountPoints;
+ DWORD dwIndex;
+
+ lock_ObtainMutex(&cm_Freelance_Lock);
+
+ if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_OPENAFS_SUBKEY "\\Freelance",
+ 0,
+ KEY_READ|KEY_QUERY_VALUE,
+ &hkFreelance) == ERROR_SUCCESS)
+ {
+ RegQueryInfoKey( hkFreelance,
+ NULL, /* lpClass */
+ NULL, /* lpcClass */
+ NULL, /* lpReserved */
+ NULL, /* lpcSubKeys */
+ NULL, /* lpcMaxSubKeyLen */
+ NULL, /* lpcMaxClassLen */
+ &dwMountPoints, /* lpcValues */
+ NULL, /* lpcMaxValueNameLen */
+ NULL, /* lpcMaxValueLen */
+ NULL, /* lpcbSecurityDescriptor */
+ NULL /* lpftLastWriteTime */
+ );
+
+ for ( dwIndex = 0; dwIndex < dwMountPoints; dwIndex++ ) {
+ TCHAR szValueName[16];
+ DWORD dwValueSize = 16;
+ dwSize = sizeof(line);
+ RegEnumValue( hkFreelance, dwIndex, szValueName, &dwValueSize, NULL,
+ &dwType, line, &dwSize);
+
+ cp=strchr(line, '#');
+ if (!cp)
+ cp=strchr(line, '%');
+ memcpy(shortname, line, cp-line);
+ shortname[cp-line]=0;
+
+ if (!strcmp(shortname, filename)) {
+ found = 1;
+ break;
+ }
+ }
+ for ( dwIndex = 0; dwIndex < dwMountPoints; dwIndex++ ) {
+ TCHAR szValueName[16];
+ DWORD dwValueSize = 16;
+ dwSize = sizeof(line);
+ RegEnumValue( hkFreelance, dwIndex, szValueName, &dwValueSize, NULL,
+ &dwType, line, &dwSize);
+
+ cp=strchr(line, '#');
+ if (!cp)
+ cp=strchr(line, '%');
+ memcpy(shortname, line, cp-line);
+ shortname[cp-line]=0;
+
+ if (!stricmp(shortname, filename)) {
+ found = 1;
+ break;
+ }
+
+ if (prefix_ok && strlen(shortname) - strlen(filename) == 1 && !strncmp(shortname, filename, strlen(filename))) {
+ found = 1;
+ break;
+ }
+ }
+ RegCloseKey(hkFreelance);
+ }
+
+ lock_ReleaseMutex(&cm_Freelance_Lock);
+
+ return found;
+}
+
+long cm_FreelanceSymlinkExists(char * filename, int prefix_ok)
+{
+ char* cp;
+ char line[512];
+ char shortname[200];
+ int found = 0;
+ HKEY hkFreelance = 0;
+ DWORD dwType, dwSize;
+ DWORD dwSymlinks;
+ DWORD dwIndex;
+
+ lock_ObtainMutex(&cm_Freelance_Lock);
+
+ if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_OPENAFS_SUBKEY "\\Freelance\\Symlinks",
+ 0,
+ KEY_READ|KEY_QUERY_VALUE,
+ &hkFreelance) == ERROR_SUCCESS)
+ {
+ RegQueryInfoKey( hkFreelance,
+ NULL, /* lpClass */
+ NULL, /* lpcClass */
+ NULL, /* lpReserved */
+ NULL, /* lpcSubKeys */
+ NULL, /* lpcMaxSubKeyLen */
+ NULL, /* lpcMaxClassLen */
+ &dwSymlinks, /* lpcValues */
+ NULL, /* lpcMaxValueNameLen */
+ NULL, /* lpcMaxValueLen */
+ NULL, /* lpcbSecurityDescriptor */
+ NULL /* lpftLastWriteTime */
+ );
+
+ for ( dwIndex = 0; dwIndex < dwSymlinks; dwIndex++ ) {
+ TCHAR szValueName[16];
+ DWORD dwValueSize = 16;
+ dwSize = sizeof(line);
+ RegEnumValue( hkFreelance, dwIndex, szValueName, &dwValueSize, NULL,
+ &dwType, line, &dwSize);
+
+ cp=strchr(line, ':');
+ memcpy(shortname, line, cp-line);
+ shortname[cp-line]=0;
+
+ if (!strcmp(shortname, filename)) {
+ found = 1;
+ break;
+ }
+
+ if (prefix_ok && strlen(shortname) - strlen(filename) == 1 && !strncmp(shortname, filename, strlen(filename))) {
+ found = 1;
+ break;
+ }
+ }
+ for ( dwIndex = 0; dwIndex < dwSymlinks; dwIndex++ ) {
+ TCHAR szValueName[16];
+ DWORD dwValueSize = 16;
+ dwSize = sizeof(line);
+ RegEnumValue( hkFreelance, dwIndex, szValueName, &dwValueSize, NULL,
+ &dwType, line, &dwSize);
+
+ cp=strchr(line, ':');
+ memcpy(shortname, line, cp-line);
+ shortname[cp-line]=0;
+
+ if (!stricmp(shortname, filename)) {
+ found = 1;
+ break;
+ }
+ }
+ RegCloseKey(hkFreelance);
+ }
+
+ lock_ReleaseMutex(&cm_Freelance_Lock);
+
+ return found;
}
+#endif
long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw, cm_fid_t *fidp)
{
osi_LogSaveString(afsd_logp,cellname),
osi_LogSaveString(afsd_logp,volume),
rw ? "rw" : "ro");
+
+ if ( filename[0] == '\0' || cellname[0] == '\0' || volume[0] == '\0' )
+ return -1;
+
if (cellname[0] == '.') {
if (!cm_GetCell_Gen(&cellname[1], fullname, CM_FLAG_CREATE))
return -1;
if (!cm_GetCell_Gen(cellname, fullname, CM_FLAG_CREATE))
return -1;
}
+
+#if !defined(DJGPP)
+ if ( cm_FreelanceMountPointExists(filename, 0) ||
+ cm_FreelanceSymlinkExists(filename, 0) )
+ return -1;
+#endif
osi_Log1(afsd_logp,"Freelance Adding Mount for Cell: %s",
osi_LogSaveString(afsd_logp,cellname));
#if !defined(DJGPP)
if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
- "SOFTWARE\\OpenAFS\\Client\\Freelance",
+ AFSREG_CLT_OPENAFS_SUBKEY "\\Freelance",
0,
KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
&hkFreelance) == ERROR_SUCCESS) {
);
if (rw)
- sprintf(line, "%s%%%s:%s\n", filename, fullname, volume);
+ sprintf(line, "%s%%%s:%s", filename, fullname, volume);
else
- sprintf(line, "%s#%s:%s\n", filename, fullname, volume);
+ sprintf(line, "%s#%s:%s", filename, fullname, volume);
/* If we are adding a new value, there must be an unused name
* within the range 0 to dwMountPoints
*/
for ( dwIndex = 0; dwIndex <= dwMountPoints; dwIndex++ ) {
char szIndex[16];
+ char szMount[1024];
+
+ dwSize = sizeof(szMount);
sprintf(szIndex, "%d", dwIndex);
- if (RegQueryValueEx( hkFreelance, szIndex, 0, &dwType, NULL, &dwSize) != ERROR_SUCCESS) {
+ if (RegQueryValueEx( hkFreelance, szIndex, 0, &dwType, szMount, &dwSize) != ERROR_SUCCESS) {
/* found an unused value */
dwType = REG_SZ;
- dwSize = strlen(line) + 1;
+ dwSize = (DWORD)strlen(line) + 1;
RegSetValueEx( hkFreelance, szIndex, 0, dwType, line, dwSize);
break;
+ } else {
+ int len = (int)strlen(filename);
+ if ( dwType == REG_SZ && !strncmp(filename, szMount, len) &&
+ (szMount[len] == '%' || szMount[len] == '#')) {
+ /* Replace the existing value */
+ dwType = REG_SZ;
+ dwSize = (DWORD)strlen(line) + 1;
+ RegSetValueEx( hkFreelance, szIndex, 0, dwType, line, dwSize);
+ break;
+ }
}
}
RegCloseKey(hkFreelance);
lock_ObtainMutex(&cm_Freelance_Lock);
-
#if !defined(DJGPP)
if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
- "SOFTWARE\\OpenAFS\\Client\\Freelance",
+ AFSREG_CLT_OPENAFS_SUBKEY "\\Freelance",
0,
KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
&hkFreelance) == ERROR_SUCCESS) {
return 0;
}
+long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp)
+{
+ char line[512];
+ char fullname[200];
+ int alias = 0;
+#if !defined(DJGPP)
+ HKEY hkFreelanceSymlinks = 0;
+ DWORD dwType, dwSize;
+ DWORD dwSymlinks;
+ DWORD dwIndex;
+#endif
+
+ /* before adding, verify the filename. If it is already in use, either as
+ * as mount point or a cellname, do not permit the creation of the symlink.
+ */
+ osi_Log2(afsd_logp,"Freelance Add Symlink request: filename=%s destination=%s",
+ osi_LogSaveString(afsd_logp,filename),
+ osi_LogSaveString(afsd_logp,destination));
+
+ if ( filename[0] == '\0' || destination[0] == '\0' )
+ return CM_ERROR_INVAL;
+
+ fullname[0] = '\0';
+ if (filename[0] == '.') {
+ cm_GetCell_Gen(&filename[1], fullname, CM_FLAG_CREATE);
+ if (stricmp(&filename[1],fullname) == 0)
+ return CM_ERROR_EXISTS;
+ } else {
+ cm_GetCell_Gen(filename, fullname, CM_FLAG_CREATE);
+ if (stricmp(filename,fullname) == 0)
+ return CM_ERROR_EXISTS;
+ }
+
+#if !defined(DJGPP)
+ if ( cm_FreelanceMountPointExists(filename, 0) ||
+ cm_FreelanceSymlinkExists(filename, 0) )
+ return CM_ERROR_EXISTS;
+#endif
+
+ lock_ObtainMutex(&cm_Freelance_Lock);
+
+#if !defined(DJGPP)
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_OPENAFS_SUBKEY "\\Freelance\\Symlinks",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+ NULL,
+ &hkFreelanceSymlinks,
+ NULL) == ERROR_SUCCESS) {
+
+ RegQueryInfoKey( hkFreelanceSymlinks,
+ NULL, /* lpClass */
+ NULL, /* lpcClass */
+ NULL, /* lpReserved */
+ NULL, /* lpcSubKeys */
+ NULL, /* lpcMaxSubKeyLen */
+ NULL, /* lpcMaxClassLen */
+ &dwSymlinks, /* lpcValues */
+ NULL, /* lpcMaxValueNameLen */
+ NULL, /* lpcMaxValueLen */
+ NULL, /* lpcbSecurityDescriptor */
+ NULL /* lpftLastWriteTime */
+ );
+
+ sprintf(line, "%s:%s.", filename, destination);
+
+ /* If we are adding a new value, there must be an unused name
+ * within the range 0 to dwSymlinks
+ */
+ for ( dwIndex = 0; dwIndex <= dwSymlinks; dwIndex++ ) {
+ char szIndex[16];
+ char szLink[1024];
+
+ dwSize = sizeof(szLink);
+ sprintf(szIndex, "%d", dwIndex);
+ if (RegQueryValueEx( hkFreelanceSymlinks, szIndex, 0, &dwType, szLink, &dwSize) != ERROR_SUCCESS) {
+ /* found an unused value */
+ dwType = REG_SZ;
+ dwSize = (DWORD)strlen(line) + 1;
+ RegSetValueEx( hkFreelanceSymlinks, szIndex, 0, dwType, line, dwSize);
+ break;
+ } else {
+ int len = (int)strlen(filename);
+ if ( dwType == REG_SZ && !strncmp(filename, szLink, len) && szLink[len] == ':') {
+ /* Replace the existing value */
+ dwType = REG_SZ;
+ dwSize = (DWORD)strlen(line) + 1;
+ RegSetValueEx( hkFreelanceSymlinks, szIndex, 0, dwType, line, dwSize);
+ break;
+ }
+ }
+ }
+ RegCloseKey(hkFreelanceSymlinks);
+ }
+#endif
+ lock_ReleaseMutex(&cm_Freelance_Lock);
+
+ /* cm_reInitLocalMountPoints(); */
+ if (fidp) {
+ fidp->unique = 1;
+ fidp->vnode = cm_noLocalMountPoints + 1; /* vnode value of last mt pt */
+ }
+ cm_noteLocalMountPointChange();
+ return 0;
+}
+
+long cm_FreelanceRemoveSymlink(char *toremove)
+{
+ char* cp;
+ char line[512];
+ char shortname[200];
+ int found=0;
+#if !defined(DJGPP)
+ HKEY hkFreelanceSymlinks = 0;
+ DWORD dwType, dwSize;
+ DWORD dwSymlinks;
+ DWORD dwIndex;
+#endif
+
+ lock_ObtainMutex(&cm_Freelance_Lock);
+
+#if !defined(DJGPP)
+ if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_OPENAFS_SUBKEY "\\Freelance\\Symlinks",
+ 0,
+ KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+ &hkFreelanceSymlinks) == ERROR_SUCCESS) {
+
+ RegQueryInfoKey( hkFreelanceSymlinks,
+ NULL, /* lpClass */
+ NULL, /* lpcClass */
+ NULL, /* lpReserved */
+ NULL, /* lpcSubKeys */
+ NULL, /* lpcMaxSubKeyLen */
+ NULL, /* lpcMaxClassLen */
+ &dwSymlinks, /* lpcValues */
+ NULL, /* lpcMaxValueNameLen */
+ NULL, /* lpcMaxValueLen */
+ NULL, /* lpcbSecurityDescriptor */
+ NULL /* lpftLastWriteTime */
+ );
+
+ for ( dwIndex = 0; dwIndex < dwSymlinks; dwIndex++ ) {
+ TCHAR szValueName[16];
+ DWORD dwValueSize = 16;
+ dwSize = sizeof(line);
+ RegEnumValue( hkFreelanceSymlinks, dwIndex, szValueName, &dwValueSize, NULL,
+ &dwType, line, &dwSize);
+
+ cp=strchr(line, ':');
+ memcpy(shortname, line, cp-line);
+ shortname[cp-line]=0;
+
+ if (!strcmp(shortname, toremove)) {
+ RegDeleteValue( hkFreelanceSymlinks, szValueName );
+ break;
+ }
+ }
+ RegCloseKey(hkFreelanceSymlinks);
+ }
+#endif
+
+ lock_ReleaseMutex(&cm_Freelance_Lock);
+ cm_noteLocalMountPointChange();
+ return 0;
+}
#endif /* AFS_FREELANCE_CLIENT */