2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 #include <afs/param.h>
21 #include "results_dlg.h"
22 #include "volume_inf.h"
23 #include "mount_points_dlg.h"
24 #include "hourglass.h"
25 #include "down_servers_dlg.h"
28 #include <afs/param.h>
34 #include <WINNT\afsreg.h>
38 #define PCCHAR(str) ((char *)(const char *)(str))
45 #define MAXINSIZE 1300 /* pioctl complains if data is larger than this */
46 #define VMSGSIZE 128 /* size of msg buf in volume hdr */
48 #define MAXCELLCHARS 64
49 #define MAXHOSTCHARS 64
50 #define MAXHOSTSPERCELL 8
53 char name[MAXCELLCHARS];
56 struct sockaddr_in hostAddr[MAXHOSTSPERCELL];
57 char hostName[MAXHOSTSPERCELL][MAXHOSTCHARS];
61 static char space[MAXSIZE];
62 static char tspace[1024];
64 // #define LOGGING_ON // Enable this to log certain pioctl calls
67 static char *szLogFileName = "afsguilog.txt";
70 FILE *OpenFile(char *file, char *rwp)
77 code = GetWindowsDirectory(wdir, sizeof(wdir));
78 if (code == 0 || code > sizeof(wdir))
81 /* add trailing backslash, if required */
83 if (wdir[tlen - 1] != '\\')
88 fp = fopen(wdir, rwp);
93 CString StripPath(CString& strPath)
95 int nIndex = strPath.ReverseFind('\\');
97 CString strFile = strPath.Mid(nIndex + 1);
98 if (strFile.IsEmpty())
104 CStringArray& StripPath(CStringArray& files)
106 for (int i = 0; i < files.GetSize(); i++)
107 files[i] = StripPath(files[i]);
112 void Flush(const CStringArray& files)
115 struct ViceIoctl blob;
120 for (int i = 0; i < files.GetSize(); i++) {
121 blob.in_size = blob.out_size = 0;
123 code = pioctl(PCCHAR(files[i]), VIOCFLUSH, &blob, 0);
127 ShowMessageBox(IDS_FLUSH_FAILED, MB_ICONEXCLAMATION, IDS_FLUSH_FAILED, files[i]);
129 ShowMessageBox(IDS_FLUSH_ERROR, MB_ICONEXCLAMATION, IDS_FLUSH_ERROR, files[i], strerror(errno));
134 ShowMessageBox(IDS_FLUSH_OK, MB_ICONEXCLAMATION, IDS_FLUSH_OK);
137 void FlushVolume(const CStringArray& files)
140 struct ViceIoctl blob;
145 for (int i = 0; i < files.GetSize(); i++) {
146 blob.in_size = blob.out_size = 0;
148 code = pioctl(PCCHAR(files[i]), VIOC_FLUSHVOLUME, &blob, 0);
151 ShowMessageBox(IDS_FLUSH_VOLUME_ERROR, MB_ICONEXCLAMATION, IDS_FLUSH_VOLUME_ERROR, files[i], strerror(errno));
156 ShowMessageBox(IDS_FLUSH_VOLUME_OK, MB_ICONEXCLAMATION, IDS_FLUSH_VOLUME_OK);
159 void WhichCell(CStringArray& files)
162 struct ViceIoctl blob;
167 CStringArray results;
173 for (int i = 0; i < files.GetSize(); i++) {
175 blob.out_size = MAXSIZE;
178 code = pioctl(PCCHAR(files[i]), VIOC_FILE_CELL_NAME, &blob, 1);
180 if (code == ENOENT) {
181 LoadString (str, IDS_CANT_GET_CELL);
184 results.Add(GetAfsError(errno));
189 LoadString (str, IDS_SHOW_CELL);
190 LoadString (str2, IDS_SHOW_CELL_COLUMN);
191 CResultsDlg dlg(SHOW_CELL_HELP_ID);
192 dlg.SetContents(str, str2, StripPath(files), results);
199 struct ViceIoctl blob;
204 blob.in = (char *) 0;
205 blob.out_size = MAXSIZE;
208 code = pioctl((char *) 0, VIOC_GET_WS_CELL, &blob, 1);
211 //Die(errno, (char *) 0);
214 //printf("This workstation belongs to cell '%s'\n", space);
220 struct ViceIoctl blob;
224 code = pioctl(0, VIOCCKBACK, &blob, 1);
226 ShowMessageBox(IDS_CHECK_VOLUMES_ERROR, MB_ICONEXCLAMATION, IDS_CHECK_VOLUMES_ERROR, GetAfsError(errno, CString()));
230 ShowMessageBox(IDS_CHECK_VOLUMES_OK, MB_OK, IDS_CHECK_VOLUMES_OK);
235 void SetCacheSizeCmd(LONG nNewCacheSize)
238 struct ViceIoctl blob;
242 blob.in = (char *) &nNewCacheSize;
243 blob.in_size = sizeof(LONG);
246 code = pioctl(0, VIOCSETCACHESIZE, &blob, 1);
248 // Die(errno, (char *) 0);
250 // printf("New cache size set.\n");
253 void WhereIs(CStringArray& files)
256 struct ViceIoctl blob;
257 CStringArray servers;
258 CStringArray resultFiles;
264 for (int i = 0; i < files.GetSize(); i++) {
265 blob.out_size = MAXSIZE;
268 memset(space, 0, sizeof(space));
270 code = pioctl(PCCHAR(files[i]), VIOCWHEREIS, &blob, 1);
272 resultFiles.Add(StripPath(files[i]));
273 servers.Add(GetAfsError(errno));
277 LONG *hosts = (LONG *)space;
281 for (int j = 0; j < MAXHOSTS; j++) {
284 char *hostName = hostutil_GetNameByINet(hosts[j]);
286 resultFiles.Add(StripPath(files[i]));
289 resultFiles.Add(" ");
290 servers.Add(hostName);
294 LoadString (str, IDS_SHOW_FS);
295 LoadString (str2, IDS_SHOW_FS_COLUMN);
296 CResultsDlg dlg(SHOW_FILE_SERVERS_HELP_ID);
297 dlg.SetContents(str, str2, resultFiles, servers);
301 CString GetAfsError(int code, const char *filename)
305 if (code == EINVAL) {
307 strMsg.Format("Invalid argument; it is possible that the file is not in AFS");
309 strMsg.Format("Invalid argument");
310 } else if (code == ENOENT) {
312 strMsg.Format("The file does not exist");
314 strMsg.Format("No such file returned");
315 } else if (code == EROFS) {
316 strMsg.Format("You can not change a backup or readonly volume");
317 } else if (code == EACCES || code == EPERM) {
318 strMsg.Format("You do not have the required rights to do this operation");
319 } else if (code == ENODEV) {
320 strMsg.Format("AFS service may not have started");
321 } else if (code == ESRCH) {
322 strMsg.Format("Cell name not recognized");
323 } else if (code == ETIMEDOUT) {
324 strMsg.Format("Connection timed out");
325 } else if (code == EPIPE) {
326 strMsg.Format("Volume name or ID not recognized");
328 strMsg.Format("Error 0x%x occurred", code);
335 /************************************************************************
336 ************************** ACL Code *************************************
337 ************************************************************************/
339 typedef char sec_rgy_name_t[1025]; /* A DCE definition */
342 struct AclEntry *next;
348 int dfs; // Originally true if a dfs acl; now also the type
349 // of the acl (1, 2, or 3, corresponding to object,
350 // initial dir, or initial object).
351 sec_rgy_name_t cell; // DFS cell name
354 struct AclEntry *pluslist;
355 struct AclEntry *minuslist;
358 int foldcmp (register char *a, register char *b)
364 if (t >= 'A' && t <= 'Z') t += 0x20;
365 if (u >= 'A' && u <= 'Z') u += 0x20;
366 if (t != u) return 1;
367 if (t == 0) return 0;
371 extern "C" void ZapList(struct AclEntry *alist)
373 register struct AclEntry *tp, *np;
375 for (tp = alist; tp; tp = np) {
381 extern "C" void ZapAcl (struct Acl *acl)
383 ZapList(acl->pluslist);
384 ZapList(acl->minuslist);
388 extern "C" int PruneList (struct AclEntry **ae, int dfs)
390 struct AclEntry **lp = ae;
391 struct AclEntry *te, *ne;
394 for (te = *ae; te; te = ne) {
395 if ((!dfs && te->rights == 0) || te->rights == -1) {
410 char *SkipLine (register char *astr)
412 while (*astr != '\n')
420 /* tell if a name is 23 or -45 (digits or minus digits), which are bad names we must prune */
421 static int BadName(register char *aname)
425 /* all must be '-' or digit to be bad */
426 while (tc = *aname++) {
427 if ((tc != '-') && (tc < '0' || tc > '9'))
434 CString GetRightsString(register LONG arights, int dfs)
439 if (arights & PRSFS_READ) str += "r";
440 if (arights & PRSFS_LOOKUP) str += "l";
441 if (arights & PRSFS_INSERT) str += "i";
442 if (arights & PRSFS_DELETE) str += "d";
443 if (arights & PRSFS_WRITE) str += "w";
444 if (arights & PRSFS_LOCK) str += "k";
445 if (arights & PRSFS_ADMINISTER) str += "a";
449 if (arights & DFS_READ) str += "r"; else str += "-";
450 if (arights & DFS_WRITE) str += "w"; else printf("-");
451 if (arights & DFS_EXECUTE) str += "x"; else printf("-");
452 if (arights & DFS_CONTROL) str += "c"; else printf("-");
453 if (arights & DFS_INSERT) str += "i"; else printf("-");
454 if (arights & DFS_DELETE) str += "d"; else printf("-");
455 if (arights & (DFS_USRALL)) str += "+";
462 char *AclToString(struct Acl *acl)
464 static char mydata[MAXSIZE];
465 char tstring[MAXSIZE];
470 sprintf(dfsstring, " dfs:%d %s", acl->dfs, acl->cell);
473 sprintf(mydata, "%d%s\n%d\n", acl->nplus, dfsstring, acl->nminus);
475 for(tp = acl->pluslist; tp; tp = tp->next) {
476 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
477 strcat(mydata, tstring);
480 for(tp = acl->minuslist; tp; tp = tp->next) {
481 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
482 strcat(mydata, tstring);
488 struct Acl *EmptyAcl(const CString& strCellName)
490 register struct Acl *tp;
492 tp = (struct Acl *)malloc(sizeof (struct Acl));
493 tp->nplus = tp->nminus = 0;
494 tp->pluslist = tp->minuslist = 0;
496 strcpy(tp->cell, strCellName);
501 struct Acl *ParseAcl(char *astr)
503 int nplus, nminus, i, trights;
505 struct AclEntry *first, *last, *tl;
508 ta = (struct Acl *) malloc (sizeof (struct Acl));
510 sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
511 astr = SkipLine(astr);
512 sscanf(astr, "%d", &ta->nminus);
513 astr = SkipLine(astr);
520 for(i = 0; i < nplus; i++) {
521 sscanf(astr, "%100s %d", tname, &trights);
522 astr = SkipLine(astr);
523 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
526 strcpy(tl->name, tname);
527 tl->rights = trights;
533 ta->pluslist = first;
537 for(i=0; i < nminus; i++) {
538 sscanf(astr, "%100s %d", tname, &trights);
539 astr = SkipLine(astr);
540 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
543 strcpy(tl->name, tname);
544 tl->rights = trights;
550 ta->minuslist = first;
555 /* clean up an access control list of its bad entries; return 1 if we made
556 any changes to the list, and 0 otherwise */
557 extern "C" int CleanAcl(struct Acl *aa)
559 register struct AclEntry *te, **le, *ne;
564 /* Don't correct DFS ACL's for now */
568 /* prune out bad entries */
569 changes = 0; /* count deleted entries */
571 for(te = aa->pluslist; te; te = ne) {
573 if (BadName(te->name)) {
586 for(te = aa->minuslist; te; te = ne) {
588 if (BadName(te->name)) {
602 void CleanACL(CStringArray& names)
605 register struct Acl *ta;
606 struct ViceIoctl blob;
609 ShowMessageBox(IDS_CLEANACL_MSG, MB_OK, IDS_CLEANACL_MSG);
613 for (int i = 0; i < names.GetSize(); i++) {
614 blob.out_size = MAXSIZE;
618 code = pioctl(PCCHAR(names[i]), VIOCGETAL, &blob, 1);
620 ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONEXCLAMATION, 0, names[i], GetAfsError(errno));
624 ta = ParseAcl(space);
626 ShowMessageBox(IDS_CLEANACL_NOT_SUPPORTED, MB_ICONEXCLAMATION, IDS_CLEANACL_NOT_SUPPORTED, names[i]);
630 changes = CleanAcl(ta);
634 /* now set the acl */
635 blob.in = AclToString(ta);
636 blob.in_size = strlen((char *)blob.in) + 1;
639 code = pioctl(PCCHAR(names[i]), VIOCSETAL, &blob, 1);
641 if (errno == EINVAL) {
642 ShowMessageBox(IDS_CLEANACL_INVALID_ARG, MB_ICONEXCLAMATION, IDS_CLEANACL_INVALID_ARG, names[i]);
646 ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONEXCLAMATION, 0, names[i], GetAfsError(errno));
653 // Derived from fs.c's ListAclCmd
654 BOOL GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& strNegative)
657 register struct Acl *ta;
658 struct ViceIoctl blob;
660 int idf = 0; //getidf(as, parm_listacl_id);
664 blob.out_size = MAXSIZE;
666 blob.in = blob.out = space;
668 code = pioctl(PCCHAR(strDir), VIOCGETAL, &blob, 1);
670 ShowMessageBox(IDS_GETRIGHTS_ERROR, MB_ICONEXCLAMATION, IDS_GETRIGHTS_ERROR, strDir, GetAfsError(errno));
674 ta = ParseAcl(space);
676 ShowMessageBox(IDS_DFSACL_ERROR, MB_ICONEXCLAMATION, IDS_DFSACL_ERROR);
681 // printf(" Default cell = %s\n", ta->cell);
686 for (te = ta->pluslist; te; te = te->next) {
687 strNormal.Add(te->name);
688 strNormal.Add(GetRightsString(te->rights, ta->dfs));
692 if (ta->nminus > 0) {
693 for (te = ta->minuslist; te; te = te->next) {
694 strNegative.Add(te->name);
695 strNegative.Add(GetRightsString(te->rights, ta->dfs));
702 struct AclEntry *FindList(register struct AclEntry *pCurEntry, const char *entryName)
705 if (!foldcmp(pCurEntry->name, PCCHAR(entryName)))
707 pCurEntry = pCurEntry->next;
713 void ChangeList (struct Acl *pAcl, BYTE bNormalRights, const char *entryName, LONG nEntryRights)
718 struct AclEntry *pEntry;
722 pEntry = (bNormalRights ? pAcl->pluslist : pAcl->minuslist);
723 pEntry = FindList(pEntry, entryName);
725 /* Found the item already in the list. */
727 pEntry->rights = nEntryRights;
729 pAcl->nplus -= PruneList(&pAcl->pluslist, pAcl->dfs);
731 pAcl->nminus -= PruneList(&pAcl->minuslist, pAcl->dfs);
735 /* Otherwise we make a new item and plug in the new data. */
736 pEntry = (struct AclEntry *) malloc(sizeof (struct AclEntry));
739 strcpy(pEntry->name, entryName);
740 pEntry->rights = nEntryRights;
743 pEntry->next = pAcl->pluslist;
744 pAcl->pluslist = pEntry;
746 if (nEntryRights == 0 || nEntryRights == -1)
747 pAcl->nplus -= PruneList(&pAcl->pluslist, pAcl->dfs);
750 pEntry->next = pAcl->minuslist;
751 pAcl->minuslist = pEntry;
753 if (nEntryRights == 0)
754 pAcl->nminus -= PruneList(&pAcl->minuslist, pAcl->dfs);
758 enum rtype {add, destroy, deny};
760 LONG Convert(const register char *arights, int dfs, enum rtype *rtypep)
766 *rtypep = add; /* add rights, by default */
768 if (!strcmp(arights,"read"))
769 return PRSFS_READ | PRSFS_LOOKUP;
770 if (!strcmp(arights, "write"))
771 return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
772 if (!strcmp(arights, "mail"))
773 return PRSFS_INSERT | PRSFS_LOCK | PRSFS_LOOKUP;
774 if (!strcmp(arights, "all"))
775 return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
777 if (!strcmp(arights, "none")) {
778 *rtypep = destroy; /* Remove entire entry */
782 len = strlen(arights);
785 for (i = 0; i < len; i++) {
787 if (tc == 'r') mode |= PRSFS_READ;
788 else if (tc == 'l') mode |= PRSFS_LOOKUP;
789 else if (tc == 'i') mode |= PRSFS_INSERT;
790 else if (tc == 'd') mode |= PRSFS_DELETE;
791 else if (tc == 'w') mode |= PRSFS_WRITE;
792 else if (tc == 'k') mode |= PRSFS_LOCK;
793 else if (tc == 'a') mode |= PRSFS_ADMINISTER;
795 fprintf(stderr, "illegal rights character '%c'.\n", tc);
802 BOOL SaveACL(const CString& strCellName, const CString& strDir, const CStringArray& normal, const CStringArray& negative)
805 struct ViceIoctl blob;
813 pAcl = EmptyAcl(strCellName);
815 // Set its normal rights
817 for (i = 0; i < normal.GetSize(); i += 2) {
818 rights = Convert(normal[i + 1], 0, &rtype);
819 ChangeList(pAcl, TRUE, normal[i], rights);
822 // Set its negative rights
823 for (i = 0; i < negative.GetSize(); i += 2) {
824 rights = Convert(negative[i + 1], 0, &rtype);
825 ChangeList(pAcl, FALSE, negative[i], rights);
829 blob.in = AclToString(pAcl);
831 blob.in_size = 1 + strlen((const char *)blob.in);
833 code = pioctl(PCCHAR(strDir), VIOCSETAL, &blob, 1);
836 ShowMessageBox(IDS_SAVE_ACL_EINVAL_ERROR, MB_ICONEXCLAMATION, IDS_SAVE_ACL_EINVAL_ERROR, strDir);
838 ShowMessageBox(IDS_SAVE_ACL_ERROR, MB_ICONEXCLAMATION, IDS_SAVE_ACL_ERROR, strDir, GetAfsError(errno, strDir));
846 BOOL CopyACL(const CString& strToDir, const CStringArray& normal, const CStringArray& negative, BOOL bClear)
849 struct ViceIoctl blob;
851 int idf = 0; // getidf(as, parm_copyacl_id);
855 // Get ACL to copy to
856 blob.out_size = MAXSIZE;
858 blob.in = blob.out = space;
860 code = pioctl(PCCHAR(strToDir), VIOCGETAL, &blob, 1);
862 ShowMessageBox(IDS_ACL_READ_ERROR, MB_ICONEXCLAMATION, IDS_ACL_READ_ERROR, strToDir, GetAfsError(errno, strToDir));
867 pToAcl = EmptyAcl(space);
869 pToAcl = ParseAcl(space);
874 ShowMessageBox(IDS_NO_DFS_COPY_ACL, MB_ICONEXCLAMATION, IDS_NO_DFS_COPY_ACL, strToDir);
883 for (i = 0; i < normal.GetSize(); i += 2) {
884 LONG rights = Convert(normal[i + 1], 0, &rtype);
885 ChangeList(pToAcl, TRUE, normal[i], rights);
888 // Set negative rights
889 for (i = 0; i < negative.GetSize(); i += 2) {
890 LONG rights = Convert(negative[i + 1], 0, &rtype);
891 ChangeList(pToAcl, FALSE, normal[i], rights);
895 blob.in = AclToString(pToAcl);
897 blob.in_size = 1 + strlen((char *)blob.in);
899 code = pioctl(PCCHAR(strToDir), VIOCSETAL, &blob, 1);
903 ShowMessageBox(IDS_COPY_ACL_EINVAL_ERROR, MB_ICONEXCLAMATION, IDS_COPY_ACL_EINVAL_ERROR, strToDir);
905 ShowMessageBox(IDS_COPY_ACL_ERROR, MB_ICONEXCLAMATION, IDS_COPY_ACL_ERROR, strToDir, GetAfsError(errno, strToDir));
911 ShowMessageBox(IDS_COPY_ACL_OK, MB_OK, IDS_COPY_ACL_OK);
916 CString ParseMountPoint(const CString strFile, CString strMountPoint)
921 CString strMountPointInfo;
923 if (strMountPoint[0] == '#')
925 else if (strMountPoint[0] == '%')
926 strType = "Read/Write";
928 int nColon = strMountPoint.Find(':');
930 strCell = strMountPoint.Mid(1, nColon - 1);
931 strVolume = strMountPoint.Mid(nColon + 1);
933 strVolume = strMountPoint.Mid(1);
935 strMountPointInfo = strFile + "\t" + strVolume + "\t" + strCell + "\t" + strType;
937 return strMountPointInfo;
940 BOOL IsPathInAfs(const CHAR *strPath)
942 struct ViceIoctl blob;
948 blob.out_size = MAXSIZE;
951 code = pioctl((LPTSTR)((LPCTSTR)strPath), VIOC_FILE_CELL_NAME, &blob, 1);
958 IsFreelanceRoot(char *apath)
960 struct ViceIoctl blob;
964 blob.out_size = MAXSIZE;
967 code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
969 return !strcmp("Freelance.Local.Root",space);
970 return 1; /* assume it is because it is more restrictive that way */
973 const char * NetbiosName(void)
975 static char buffer[1024] = "AFS";
981 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
982 0, KEY_QUERY_VALUE, &parmKey);
983 if (code == ERROR_SUCCESS) {
984 dummyLen = sizeof(buffer);
985 code = RegQueryValueEx(parmKey, "NetbiosName", NULL, NULL,
986 (LPBYTE)buffer, &dummyLen);
987 RegCloseKey (parmKey);
989 strcpy(buffer, "AFS");
994 #define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins"
996 static BOOL IsAdmin (void)
998 static BOOL fAdmin = FALSE;
999 static BOOL fTested = FALSE;
1003 /* Obtain the SID for the AFS client admin group. If the group does
1004 * not exist, then assume we have AFS client admin privileges.
1006 PSID psidAdmin = NULL;
1007 DWORD dwSize, dwSize2;
1008 char pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ];
1009 char *pszRefDomain = NULL;
1010 SID_NAME_USE snu = SidTypeGroup;
1012 dwSize = sizeof(pszAdminGroup);
1014 if (!GetComputerName(pszAdminGroup, &dwSize)) {
1015 /* Can't get computer name. We return false in this case.
1016 Retain fAdmin and fTested. This shouldn't happen.*/
1023 strcat(pszAdminGroup,"\\");
1024 strcat(pszAdminGroup, AFSCLIENT_ADMIN_GROUPNAME);
1026 LookupAccountName(NULL, pszAdminGroup, NULL, &dwSize, NULL, &dwSize2, &snu);
1027 /* that should always fail. */
1029 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
1030 /* if we can't find the group, then we allow the operation */
1035 if (dwSize == 0 || dwSize2 == 0) {
1041 psidAdmin = (PSID)malloc(dwSize); memset(psidAdmin,0,dwSize);
1042 pszRefDomain = (char *)malloc(dwSize2);
1044 if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) {
1045 /* We can't lookup the group now even though we looked it up earlier.
1046 Could this happen? */
1049 /* Then open our current ProcessToken */
1052 if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken))
1055 if (!CheckTokenMembership(hToken, psidAdmin, &fAdmin)) {
1056 /* We'll have to allocate a chunk of memory to store the list of
1057 * groups to which this user belongs; find out how much memory
1061 PTOKEN_GROUPS pGroups;
1063 GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize);
1065 pGroups = (PTOKEN_GROUPS)malloc(dwSize);
1067 /* Allocate that buffer, and read in the list of groups. */
1068 if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize))
1070 /* Look through the list of group SIDs and see if any of them
1071 * matches the AFS Client Admin group SID.
1074 for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup)
1076 if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) {
1086 /* if do not have permission because we were not explicitly listed
1087 * in the Admin Client Group let's see if we are the SYSTEM account
1090 PTOKEN_USER pTokenUser;
1091 SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
1092 PSID pSidLocalSystem = 0;
1095 GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
1097 pTokenUser = (PTOKEN_USER)malloc(dwSize);
1099 if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize))
1100 gle = GetLastError();
1102 if (AllocateAndInitializeSid( &SIDAuth, 1,
1103 SECURITY_LOCAL_SYSTEM_RID,
1104 0, 0, 0, 0, 0, 0, 0,
1107 if (EqualSid(pTokenUser->User.Sid, pSidLocalSystem)) {
1111 FreeSid(pSidLocalSystem);
1129 /* return a static pointer to a buffer */
1130 static char *Parent(char *apath)
1134 strcpy(tspace, apath);
1135 tp = strrchr(tspace, '\\');
1137 *(tp+1) = 0; /* lv trailing slash so Parent("k:\foo") is "k:\" not "k:" */
1140 fs_ExtractDriveLetter(apath, tspace);
1141 strcat(tspace, ".");
1148 GetCell(char *fname, char *cellname)
1151 struct ViceIoctl blob;
1154 blob.out_size = MAXCELLCHARS;
1155 blob.out = cellname;
1157 code = pioctl(fname, VIOC_FILE_CELL_NAME, &blob, 1);
1158 return code ? errno : 0;
1162 BOOL ListMount(CStringArray& files)
1165 struct ViceIoctl blob;
1167 char orig_name[1024]; /* Original name, may be modified */
1168 char true_name[1024]; /* ``True'' dirname (e.g., symlink target) */
1169 char parent_dir[1024]; /* Parent directory of true name */
1170 register char *last_component; /* Last component of true name */
1171 CStringArray mountPoints;
1173 HOURGLASS hourglass;
1177 for (int i = 0; i < files.GetSize(); i++) {
1178 strcpy(orig_name, files[i]);
1179 strcpy(true_name, orig_name);
1182 * Find rightmost slash, if any.
1184 last_component = (char *)strrchr(true_name, '\\');
1185 if (last_component) {
1187 * Found it. Designate everything before it as the parent directory,
1188 * everything after it as the final component.
1190 strncpy(parent_dir, true_name, last_component - true_name + 1);
1191 parent_dir[last_component - true_name + 1] = 0;
1192 last_component++; /* Skip the slash */
1194 if (!IsPathInAfs(parent_dir)) {
1195 const char * nbname = NetbiosName();
1196 int len = strlen(nbname);
1198 if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
1199 parent_dir[len+2] == '\\' &&
1200 parent_dir[len+3] == '\0' &&
1201 !strnicmp(nbname,&parent_dir[2],len))
1203 sprintf(parent_dir,"\\\\%s\\all\\", nbname);
1209 * No slash appears in the given file name. Set parent_dir to the current
1210 * directory, and the last component as the given name.
1212 fs_ExtractDriveLetter(true_name, parent_dir);
1213 strcat(parent_dir, ".");
1214 last_component = true_name;
1215 fs_StripDriveLetter(true_name, true_name, sizeof(true_name));
1218 blob.in = last_component;
1219 blob.in_size = strlen(last_component) + 1;
1220 blob.out_size = MAXSIZE;
1222 memset(space, 0, MAXSIZE);
1224 code = pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
1226 int nPos = strlen(space) - 1;
1227 if (space[nPos] == '.')
1229 mountPoints.Add(ParseMountPoint(StripPath(files[i]), space));
1232 if (errno == EINVAL)
1233 mountPoints.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(files[i])));
1235 mountPoints.Add(GetMessageString(IDS_LIST_MOUNT_POINT_ERROR, GetAfsError(errno, StripPath(files[i]))));
1239 CMountPointsDlg dlg;
1240 dlg.SetMountPoints(mountPoints);
1246 BOOL MakeMount(const CString& strDir, const CString& strVolName, const CString& strCellName, BOOL bRW)
1249 register char *cellName;
1250 char localCellName[128];
1251 struct afsconf_cell info;
1252 struct ViceIoctl blob;
1254 char path[1024] = "";
1256 HOURGLASS hourglass;
1258 ASSERT(strVolName.GetLength() < 64);
1260 if (strCellName.GetLength() > 0) /* cell name specified */
1261 cellName = PCCHAR(strCellName);
1263 cellName = (char *) 0;
1265 parent = Parent(PCCHAR(strDir));
1266 if (!IsPathInAfs(parent)) {
1267 const char * nbname = NetbiosName();
1268 int len = strlen(nbname);
1270 if (parent[0] == '\\' && parent[1] == '\\' &&
1271 parent[len+2] == '\\' &&
1272 parent[len+3] == '\0' &&
1273 !strnicmp(nbname,&parent[2],len))
1275 sprintf(path,"%sall\\%s", parent, &(PCCHAR(strDir)[strlen(parent)]));
1276 parent = Parent(path);
1277 if (!IsPathInAfs(parent)) {
1278 ShowMessageBox(IDS_MAKE_MP_NOT_AFS_ERROR, MB_ICONEXCLAMATION, IDS_MAKE_MP_NOT_AFS_ERROR);
1282 ShowMessageBox(IDS_MAKE_MP_NOT_AFS_ERROR, MB_ICONEXCLAMATION, IDS_MAKE_MP_NOT_AFS_ERROR);
1287 if ( strlen(path) == 0 )
1288 strcpy(path, PCCHAR(strDir));
1290 if ( IsFreelanceRoot(parent) ) {
1292 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONEXCLAMATION, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
1298 blob.out_size = sizeof(localCellName);
1299 blob.out = localCellName;
1300 code = pioctl(parent, VIOC_GET_WS_CELL, &blob, 1);
1302 cellName = localCellName;
1306 GetCell(parent,space);
1309 code = GetCellName(cellName?cellName:space, &info);
1314 if (bRW) /* if -rw specified */
1319 /* If cellular mount point, prepend cell prefix */
1321 strcat(space, info.name);
1325 strcat(space, strVolName); /* append volume name */
1326 strcat(space, "."); /* stupid convention; these end with a period */
1328 /* create symlink with a special pioctl for Windows NT, since it doesn't
1329 * have a symlink system call.
1332 blob.in_size = 1 + strlen(space);
1335 code = pioctl(path, VIOC_AFS_CREATE_MT_PT, &blob, 0);
1338 ShowMessageBox(IDS_MOUNT_POINT_ERROR, MB_ICONEXCLAMATION, IDS_MOUNT_POINT_ERROR, GetAfsError(errno, strDir));
1347 long fs_ExtractDriveLetter(const char *inPathp, char *outPathp)
1349 if (inPathp[0] != 0 && inPathp[1] == ':') {
1350 /* there is a drive letter */
1351 *outPathp++ = *inPathp++;
1352 *outPathp++ = *inPathp++;
1360 /* strip the drive letter from a component */
1361 long fs_StripDriveLetter(const char *inPathp, char *outPathp, long outSize)
1363 char tempBuffer[1000];
1364 strcpy(tempBuffer, inPathp);
1365 if (tempBuffer[0] != 0 && tempBuffer[1] == ':') {
1366 /* drive letter present */
1367 strcpy(outPathp, tempBuffer+2);
1370 /* no drive letter present */
1371 strcpy(outPathp, tempBuffer);
1377 BOOL RemoveSymlink(const char * linkName)
1381 struct ViceIoctl blob;
1383 char lsbuffer[1024];
1384 char tpbuffer[1024];
1387 HOURGLASS hourglass;
1389 tp = (char *) strrchr(linkName, '\\');
1391 tp = (char *) strrchr(linkName, '/');
1393 strncpy(tbuffer, linkName, code=tp-linkName+1); /* the dir name */
1395 tp++; /* skip the slash */
1397 if (!IsPathInAfs(tbuffer)) {
1398 const char * nbname = NetbiosName();
1399 int len = strlen(nbname);
1401 if (tbuffer[0] == '\\' && tbuffer[1] == '\\' &&
1402 tbuffer[len+2] == '\\' &&
1403 tbuffer[len+3] == '\0' &&
1404 !strnicmp(nbname,&tbuffer[2],len))
1406 sprintf(tbuffer,"\\\\%s\\all\\", nbname);
1411 fs_ExtractDriveLetter(linkName, tbuffer);
1412 strcat(tbuffer, ".");
1413 fs_StripDriveLetter(tp, tpbuffer, 0);
1417 if ( IsFreelanceRoot(tbuffer) && !IsAdmin() ) {
1418 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONEXCLAMATION, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
1423 blob.in_size = strlen(tp)+1;
1424 blob.out = lsbuffer;
1425 blob.out_size = sizeof(lsbuffer);
1426 code = pioctl(tbuffer, VIOC_LISTSYMLINK, &blob, 0);
1431 blob.in_size = strlen(tp)+1;
1432 return (pioctl(tbuffer, VIOC_DELSYMLINK, &blob, 0)==0);
1435 BOOL IsSymlink(const char * true_name)
1437 char parent_dir[MAXSIZE]; /*Parent directory of true name*/
1438 char strip_name[MAXSIZE];
1439 struct ViceIoctl blob;
1440 char *last_component;
1443 HOURGLASS hourglass;
1445 last_component = (char *) strrchr(true_name, '\\');
1446 if (!last_component)
1447 last_component = (char *) strrchr(true_name, '/');
1448 if (last_component) {
1450 * Found it. Designate everything before it as the parent directory,
1451 * everything after it as the final component.
1453 strncpy(parent_dir, true_name, last_component - true_name + 1);
1454 parent_dir[last_component - true_name + 1] = 0;
1455 last_component++; /*Skip the slash*/
1457 if (!IsPathInAfs(parent_dir)) {
1458 const char * nbname = NetbiosName();
1459 int len = strlen(nbname);
1461 if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
1462 parent_dir[len+2] == '\\' &&
1463 parent_dir[len+3] == '\0' &&
1464 !strnicmp(nbname,&parent_dir[2],len))
1466 sprintf(parent_dir,"\\\\%s\\all\\", nbname);
1472 * No slash appears in the given file name. Set parent_dir to the current
1473 * directory, and the last component as the given name.
1475 fs_ExtractDriveLetter(true_name, parent_dir);
1476 strcat(parent_dir, ".");
1477 last_component = strip_name;
1478 fs_StripDriveLetter(true_name, strip_name, sizeof(strip_name));
1481 blob.in = last_component;
1482 blob.in_size = strlen(last_component)+1;
1483 blob.out_size = MAXSIZE;
1485 memset(space, 0, MAXSIZE);
1486 code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1);
1491 BOOL IsMountPoint(const char * name)
1493 register LONG code = 0;
1494 struct ViceIoctl blob;
1496 char lsbuffer[1024];
1498 char szCurItem[1024];
1500 strcpy(szCurItem, name);
1502 tp = (char *)strrchr(szCurItem, '\\');
1504 strncpy(tbuffer, szCurItem, code = tp - szCurItem + 1); /* the dir name */
1506 tp++; /* skip the slash */
1508 if (!IsPathInAfs(tbuffer)) {
1509 const char * nbname = NetbiosName();
1510 int len = strlen(nbname);
1512 if (tbuffer[0] == '\\' && tbuffer[1] == '\\' &&
1513 tbuffer[len+2] == '\\' &&
1514 tbuffer[len+3] == '\0' &&
1515 !strnicmp(nbname,&tbuffer[2],len))
1517 sprintf(tbuffer,"\\\\%s\\all\\", nbname);
1521 fs_ExtractDriveLetter(szCurItem, tbuffer);
1522 strcat(tbuffer, ".");
1524 fs_StripDriveLetter(tp, tp, 0);
1528 blob.in_size = strlen(tp)+1;
1529 blob.out = lsbuffer;
1530 blob.out_size = sizeof(lsbuffer);
1532 code = pioctl(tbuffer, VIOC_AFS_STAT_MT_PT, &blob, 0);
1539 * Delete AFS mount points. Variables are used as follows:
1540 * tbuffer: Set to point to the null-terminated directory name of the mount point
1541 * (or ``.'' if none is provided)
1542 * tp: Set to point to the actual name of the mount point to nuke.
1544 BOOL RemoveMount(CStringArray& files)
1546 register LONG code = 0;
1547 struct ViceIoctl blob;
1550 char szCurItem[1024];
1552 CStringArray results;
1556 HOURGLASS hourglass;
1558 for (int i = 0; i < files.GetSize(); i++) {
1559 if (!IsMountPoint(files[i])) {
1561 if (errno == EINVAL)
1562 results.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(files[i])));
1564 results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
1565 continue; // don't bother trying
1568 strcpy(szCurItem, files[i]);
1570 tp = (char *)strrchr(szCurItem, '\\');
1572 strncpy(tbuffer, szCurItem, code = tp - szCurItem + 1); /* the dir name */
1574 tp++; /* skip the slash */
1576 if (!IsPathInAfs(tbuffer)) {
1577 const char * nbname = NetbiosName();
1578 int len = strlen(nbname);
1580 if (tbuffer[0] == '\\' && tbuffer[1] == '\\' &&
1581 tbuffer[len+2] == '\\' &&
1582 tbuffer[len+3] == '\0' &&
1583 !strnicmp(nbname,&tbuffer[2],len))
1585 sprintf(tbuffer,"\\\\%s\\all\\", nbname);
1589 fs_ExtractDriveLetter(szCurItem, tbuffer);
1590 strcat(tbuffer, ".");
1592 fs_StripDriveLetter(tp, tp, 0);
1595 if ( IsFreelanceRoot(tbuffer) && !IsAdmin() ) {
1596 results.Add(GetMessageString(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, StripPath(files[i])));
1598 continue; /* skip */
1603 blob.in_size = strlen(tp)+1;
1605 code = pioctl(tbuffer, VIOC_AFS_DELETE_MT_PT, &blob, 0);
1608 results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
1610 results.Add(GetMessageString(IDS_DELETED));
1613 LoadString (str, IDS_REMOVE_MP);
1614 LoadString (str2, IDS_REMOVE_MP_COLUMN);
1615 CResultsDlg dlg(REMOVE_MOUNT_POINTS_HELP_ID);
1616 dlg.SetContents(str, str2, StripPath(files), results);
1622 BOOL GetVolumeInfo(CString strFile, CVolInfo& volInfo)
1625 struct ViceIoctl blob;
1626 struct VolumeStatus *status;
1629 HOURGLASS hourglass;
1631 volInfo.m_strFilePath = strFile;
1632 volInfo.m_strFileName = StripPath(strFile);
1635 volInfo.m_strName = "VolumeName";
1637 volInfo.m_nQuota = 20 * 1024 * 1024;
1638 volInfo.m_nNewQuota = volInfo.m_nQuota;
1639 volInfo.m_nUsed = volInfo.m_nQuota / 2;
1640 volInfo.m_nPartSize = 50 * 1024 * 1024;
1641 volInfo.m_nPartFree = 30 * 1024 * 1024;
1642 volInfo.m_nDup = -1;
1646 blob.out_size = MAXSIZE;
1650 code = pioctl(PCCHAR(strFile), VIOCGETVOLSTAT, &blob, 1);
1652 volInfo.m_strErrorMsg = GetAfsError(errno, strFile);
1656 status = (VolumeStatus *)space;
1657 name = (char *)status + sizeof(*status);
1659 volInfo.m_strName = name;
1660 volInfo.m_nID = status->Vid;
1661 volInfo.m_nQuota = status->MaxQuota;
1662 volInfo.m_nNewQuota = status->MaxQuota;
1663 volInfo.m_nUsed = status->BlocksInUse;
1664 volInfo.m_nPartSize = status->PartMaxBlocks;
1665 volInfo.m_nPartFree = status->PartBlocksAvail;
1666 volInfo.m_nDup = -1;
1671 BOOL SetVolInfo(CVolInfo& volInfo)
1674 struct ViceIoctl blob;
1675 struct VolumeStatus *status;
1678 HOURGLASS hourglass;
1680 blob.out_size = MAXSIZE;
1681 blob.in_size = sizeof(*status) + 3; /* for the three terminating nulls */
1685 status = (VolumeStatus *)space;
1686 status->MinQuota = -1;
1687 status->MaxQuota = volInfo.m_nNewQuota;
1689 input = (char *)status + sizeof(*status);
1690 *(input++) = '\0'; /* never set name: this call doesn't change vldb */
1691 *(input++) = '\0'; // No offmsg
1692 *(input++) = '\0'; // No motd
1695 FILE *fp = OpenFile(szLogFileName, "a");
1697 fprintf(fp, "\nSetVolInfo() pioctl parms:\n");
1698 fprintf(fp, "\tpathp = %s\n\topcode = VIOCSETVOLSTAT (%d)\n\tblobp = %ld\n", PCCHAR(volInfo.m_strFilePath), VIOCSETVOLSTAT, &blob);
1699 fprintf(fp, "\t\tblobp.in = %ld (VolumeStatus *status)\n\t\tblobp.in_size = %ld\n\t\tblobp.out = %ld ((VolumeStatus *status))\n\t\tblobp.out_size = %ld\n", blob.in, blob.in_size, blob.out, blob.out_size);
1700 fprintf(fp, "\t\t\tstatus->MinQuota = %ld\n", status->MinQuota);
1701 fprintf(fp, "\t\t\tstatus->MaxQuota = %ld\n", status->MaxQuota);
1702 fprintf(fp, "\t\t\tOther status fields aren't set\n");
1703 fprintf(fp, "\t\t\t3 nulls follow the VolumeStatus structure.\n");
1704 fprintf(fp, "\tfollow = 1\n");
1709 code = pioctl(PCCHAR(volInfo.m_strFilePath), VIOCSETVOLSTAT, &blob, 1);
1711 ShowMessageBox(IDS_SET_QUOTA_ERROR, MB_ICONEXCLAMATION, IDS_SET_QUOTA_ERROR, GetAfsError(errno, volInfo.m_strName));
1718 int GetCellName(char *cellNamep, struct afsconf_cell *infop)
1720 strcpy(infop->name, cellNamep);
1724 BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast)
1727 struct ViceIoctl blob;
1730 struct afsconf_cell info;
1731 struct chservinfo checkserv;
1733 HOURGLASS hourglass;
1735 memset(&checkserv, 0, sizeof(struct chservinfo));
1736 blob.in_size = sizeof(struct chservinfo);
1737 blob.in = (caddr_t)&checkserv;
1739 blob.out_size = MAXSIZE;
1741 memset(space, 0, sizeof(afs_int32)); /* so we assure zero when nothing is copied back */
1743 if (nCellsToCheck == SPECIFIC_CELL) {
1745 GetCellName(PCCHAR(strCellName), &info);
1746 strcpy(checkserv.tbuffer,info.name);
1747 checkserv.tsize = strlen(info.name) + 1;
1749 if (nCellsToCheck != ALL_CELLS)
1751 strcpy(checkserv.tbuffer, "\0");
1752 checkserv.tsize = 0;
1755 temp |= 1; /* set fast flag */
1757 checkserv.magic = 0x12345678; /* XXX */
1758 checkserv.tflags = temp;
1759 checkserv.tinterval = -1; /* don't change current interval */
1761 code = pioctl(0, VIOCCKSERV, &blob, 1);
1763 ShowMessageBox(IDS_CHECK_SERVERS_ERROR, MB_ICONEXCLAMATION, IDS_CHECK_SERVERS_ERROR, GetAfsError(errno, CString()));
1767 memcpy(&temp, space, sizeof(LONG));
1770 ShowMessageBox(IDS_ALL_SERVERS_RUNNING, MB_OK, IDS_ALL_SERVERS_RUNNING);
1774 CStringArray servers;
1775 for (j = 0; j < MAXHOSTS; j++) {
1776 memcpy(&temp, space + j * sizeof(LONG), sizeof(LONG));
1780 char *name = hostutil_GetNameByINet(temp);
1784 CDownServersDlg dlg;
1785 dlg.SetServerNames(servers);
1791 BOOL GetTokenInfo(CStringArray& tokenInfo)
1795 time_t current_time;
1796 time_t tokenExpireTime;
1800 struct ktc_principal serviceName, clientName;
1801 struct ktc_token token;
1803 CString strTokenInfo;
1804 CString strUserName;
1805 CString strCellName;
1808 // tokenInfo.Add("");
1812 HOURGLASS hourglass;
1814 // printf("\nTokens held by the Cache Manager:\n\n");
1816 current_time = time(0);
1819 rc = ktc_ListTokens(cellNum, &cellNum, &serviceName);
1820 if (rc == KTC_NOENT) {
1822 // printf(" --End of list --\n");
1825 else if (rc == KTC_NOCM) {
1826 ShowMessageBox(IDS_GET_TOKENS_NO_AFS_SERVICE);
1827 // printf("AFS service may not have started\n");
1831 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR, MB_ICONEXCLAMATION, IDS_GET_TOKENS_UNEXPECTED_ERROR, rc);
1833 // printf("Unexpected error, code %d\n", rc);
1837 rc = ktc_GetToken(&serviceName, &token, sizeof(token), &clientName);
1839 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR2, MB_ICONEXCLAMATION, IDS_GET_TOKENS_UNEXPECTED_ERROR2,
1840 serviceName.name, serviceName.instance, serviceName.cell, rc);
1844 tokenExpireTime = token.endTime;
1846 strcpy(userName, clientName.name);
1847 if (clientName.instance[0] != 0) {
1848 strcat(userName, ".");
1849 strcat(userName, clientName.instance);
1852 BOOL bShowName = FALSE;
1854 if (userName[0] == '\0')
1855 ; //printf("Tokens");
1856 // AFS ID is not returned at this time.
1857 // else if (strncmp(userName, "AFS ID", 6) == 0)
1858 // printf("User's (%s) tokens", userName);
1859 // sscanf(userName, "(AFS ID %s)", szAfsID);
1860 else if (strncmp(userName, "Unix UID", 8) == 0)
1861 ; //printf("Tokens");
1863 strUserName = userName;
1864 // printf("User %s's tokens", userName);
1866 // printf(" for %s%s%s@%s ", serviceName.name, serviceName.instance[0] ? "." : "", serviceName.instance, serviceName.cell);
1867 strCellName = serviceName.cell;
1869 if (tokenExpireTime <= current_time)
1870 strExpir = "[>> Expired <<]";
1871 // printf("[>> Expired <<]\n");
1873 expireString = ctime(&tokenExpireTime);
1874 expireString += 4; /* Skip day of week */
1875 expireString[12] = '\0'; /* Omit secs & year */
1876 // printf("[Expires %s]\n", expireString);
1877 strExpir.Format("%s", expireString);
1880 strTokenInfo = strUserName + "\t" + strCellName + "\t" + strExpir + "\t" + strCellName;
1881 tokenInfo.Add(strTokenInfo);
1885 // printf("Press <Enter> or <Return> when finished: ");
1890 UINT MakeSymbolicLink(const char *strName, const char *strDir)
1892 struct ViceIoctl blob;
1893 char space[MAXSIZE];
1895 char path[1024] = "";
1898 HOURGLASS hourglass;
1899 static char message[2048];
1901 strcpy(path, strDir);
1902 parent = Parent(path);
1904 sprintf(message,"MakeSymbolicLink: path = %s parent = %s\n",path,parent);
1905 OutputDebugString(message);
1907 /*lets confirm its a good symlink*/
1908 if (!IsPathInAfs(path)) {
1909 const char * nbname = NetbiosName();
1910 int len = strlen(nbname);
1912 if (parent[0] == '\\' && parent[1] == '\\' &&
1913 parent[len+2] == '\\' &&
1914 parent[len+3] == '\0' &&
1915 !strnicmp(nbname,&parent[2],len))
1917 sprintf(path,"%sall\\%s", parent, &strDir[strlen(parent)]);
1918 parent = Parent(path);
1919 sprintf(message,"MakeSymbolicLink: new path = %s parent = %s\n",path,parent);
1920 OutputDebugString(message);
1922 if (!IsPathInAfs(parent)) {
1923 ShowMessageBox(IDS_MAKE_LNK_NOT_AFS_ERROR, MB_ICONEXCLAMATION, IDS_MAKE_LNK_NOT_AFS_ERROR);
1927 ShowMessageBox(IDS_MAKE_LNK_NOT_AFS_ERROR, MB_ICONEXCLAMATION, IDS_MAKE_LNK_NOT_AFS_ERROR);
1932 if ( IsFreelanceRoot(parent) && !IsAdmin() ) {
1933 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONEXCLAMATION, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
1937 LPTSTR lpsz = new TCHAR[strlen(strDir)+1];
1938 _tcscpy(lpsz, strName);
1939 strcpy(space, strDir);
1941 blob.in_size = 1 + strlen(space);
1944 code=pioctl(lpsz, VIOC_SYMLINK, &blob, 0);
1951 void ListSymbolicLinkPath(const char *strName,char *strPath,UINT nlenPath)
1953 ASSERT(nlenPath<MAX_PATH);
1954 struct ViceIoctl blob;
1955 char orig_name[MAX_PATH+1]; /*Original name, may be modified*/
1956 char true_name[MAX_PATH+1]; /*``True'' dirname (e.g., symlink target)*/
1957 char parent_dir[MAX_PATH+1]; /*Parent directory of true name*/
1958 char *last_component; /*Last component of true name*/
1961 HOURGLASS hourglass;
1963 strcpy(orig_name, strName);
1964 strcpy(true_name, orig_name);
1966 * Find rightmost slash, if any.
1968 last_component = (char *) strrchr(true_name, '\\');
1969 if (!last_component)
1970 last_component = (char *) strrchr(true_name, '/');
1971 if (last_component) {
1973 * Found it. Designate everything before it as the parent directory,
1974 * everything after it as the final component.
1976 strncpy(parent_dir, true_name, last_component - true_name + 1);
1977 parent_dir[last_component - true_name + 1] = 0;
1978 last_component++; /*Skip the slash*/
1980 if (!IsPathInAfs(parent_dir)) {
1981 const char * nbname = NetbiosName();
1982 int len = strlen(nbname);
1984 if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
1985 parent_dir[len+2] == '\\' &&
1986 parent_dir[len+3] == '\0' &&
1987 !strnicmp(nbname,&parent_dir[2],len))
1989 sprintf(parent_dir,"\\\\%s\\all\\", nbname);
1995 * No slash appears in the given file name. Set parent_dir to the current
1996 * directory, and the last component as the given name.
1998 fs_ExtractDriveLetter(true_name, parent_dir);
1999 strcat(parent_dir, ".");
2000 last_component = true_name;
2001 fs_StripDriveLetter(true_name, true_name, sizeof(true_name));
2003 blob.in = last_component;
2004 blob.in_size = strlen(last_component)+1;
2005 blob.out_size = MAXSIZE;
2007 memset(space, 0, MAXSIZE);
2008 if ((code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1)))
2009 strcpy(space,"???");
2010 ASSERT(strlen(space)<MAX_PATH);
2011 strncpy(strPath,space,nlenPath);