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
15 #include <afs/param.h>
24 #include "results_dlg.h"
25 #include "volume_inf.h"
26 #include "mount_points_dlg.h"
27 #include "hourglass.h"
28 #include "down_servers_dlg.h"
31 #include <rx/rx_globals.h>
35 #include <afs/cellconfig.h>
36 #include <afs/vldbint.h>
37 #include <afs/volser.h>
39 #include <WINNT\afsreg.h>
43 #define PCCHAR(str) ((char *)(const char *)(str))
44 #define VL_NOENT (363524L)
50 #define MAXINSIZE 1300 /* pioctl complains if data is larger than this */
51 #define VMSGSIZE 128 /* size of msg buf in volume hdr */
53 #define MAXCELLCHARS 64
54 #define MAXHOSTCHARS 64
55 #define MAXHOSTSPERCELL 8
57 static char space[MAXSIZE];
58 static char tspace[1024];
60 static struct ubik_client *uclient;
61 static int rxInitDone = 0;
62 static char pn[] = "fs";
64 // #define LOGGING_ON // Enable this to log certain pioctl calls
67 static char *szLogFileName = "afsguilog.txt";
71 VLDBInit(int noAuthFlag, struct afsconf_cell *info)
75 code = ugen_ClientInit(noAuthFlag, (char *)AFSDIR_CLIENT_ETC_DIRPATH,
76 info->name, 0, &uclient,
77 NULL, pn, rxkad_clear,
78 VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 50,
79 0, 0, USER_SERVICE_ID);
84 FILE *OpenFile(char *file, char *rwp)
91 code = GetWindowsDirectory(wdir, sizeof(wdir));
92 if (code == 0 || code > sizeof(wdir))
95 /* add trailing backslash, if required */
97 if (wdir[tlen - 1] != '\\')
102 fp = fopen(wdir, rwp);
107 CString StripPath(CString& strPath)
109 int nIndex = strPath.ReverseFind('\\');
111 CString strFile = strPath.Mid(nIndex + 1);
112 if (strFile.IsEmpty())
118 CStringArray& StripPath(CStringArray& files)
120 for (int i = 0; i < files.GetSize(); i++)
121 files[i] = StripPath(files[i]);
126 void Flush(const CStringArray& files)
129 struct ViceIoctl blob;
134 for (int i = 0; i < files.GetSize(); i++) {
135 blob.in_size = blob.out_size = 0;
137 code = pioctl(PCCHAR(files[i]), VIOCFLUSH, &blob, 0);
141 ShowMessageBox(IDS_FLUSH_FAILED, MB_ICONERROR, IDS_FLUSH_FAILED, files[i]);
143 ShowMessageBox(IDS_FLUSH_ERROR, MB_ICONERROR, IDS_FLUSH_ERROR, files[i], strerror(errno));
148 ShowMessageBox(IDS_FLUSH_OK, MB_ICONINFORMATION, IDS_FLUSH_OK);
151 void FlushVolume(const CStringArray& files)
154 struct ViceIoctl blob;
159 for (int i = 0; i < files.GetSize(); i++) {
160 blob.in_size = blob.out_size = 0;
162 code = pioctl(PCCHAR(files[i]), VIOC_FLUSHVOLUME, &blob, 0);
165 ShowMessageBox(IDS_FLUSH_VOLUME_ERROR, MB_ICONERROR, IDS_FLUSH_VOLUME_ERROR, files[i], strerror(errno));
170 ShowMessageBox(IDS_FLUSH_VOLUME_OK, MB_ICONINFORMATION, IDS_FLUSH_VOLUME_OK);
173 void WhichCell(CStringArray& files)
176 struct ViceIoctl blob;
181 CStringArray results;
187 for (int i = 0; i < files.GetSize(); i++) {
189 blob.out_size = MAXSIZE;
192 code = pioctl(PCCHAR(files[i]), VIOC_FILE_CELL_NAME, &blob, 1);
194 if (code == ENOENT) {
195 LoadString (str, IDS_CANT_GET_CELL);
198 results.Add(GetAfsError(errno));
203 LoadString (str, IDS_SHOW_CELL);
204 LoadString (str2, IDS_SHOW_CELL_COLUMN);
205 CResultsDlg dlg(SHOW_CELL_HELP_ID);
206 dlg.SetContents(str, str2, StripPath(files), results);
213 struct ViceIoctl blob;
218 blob.in = (char *) 0;
219 blob.out_size = MAXSIZE;
222 code = pioctl((char *) 0, VIOC_GET_WS_CELL, &blob, 1);
225 //Die(errno, (char *) 0);
228 //printf("This workstation belongs to cell '%s'\n", space);
234 struct ViceIoctl blob;
238 code = pioctl(0, VIOCCKBACK, &blob, 1);
240 ShowMessageBox(IDS_CHECK_VOLUMES_ERROR, MB_ICONERROR, IDS_CHECK_VOLUMES_ERROR, GetAfsError(errno, CString()));
244 ShowMessageBox(IDS_CHECK_VOLUMES_OK, MB_OK|MB_ICONINFORMATION, IDS_CHECK_VOLUMES_OK);
249 void SetCacheSizeCmd(LONG nNewCacheSize)
252 struct ViceIoctl blob;
256 blob.in = (char *) &nNewCacheSize;
257 blob.in_size = sizeof(LONG);
260 code = pioctl(0, VIOCSETCACHESIZE, &blob, 1);
262 // Die(errno, (char *) 0);
264 // printf("New cache size set.\n");
267 void WhereIs(CStringArray& files)
270 struct ViceIoctl blob;
271 CStringArray servers;
272 CStringArray resultFiles;
278 for (int i = 0; i < files.GetSize(); i++) {
279 blob.out_size = MAXSIZE;
282 memset(space, 0, sizeof(space));
284 code = pioctl(PCCHAR(files[i]), VIOCWHEREIS, &blob, 1);
286 resultFiles.Add(StripPath(files[i]));
287 servers.Add(GetAfsError(errno));
291 LONG *hosts = (LONG *)space;
295 for (int j = 0; j < MAXHOSTS; j++) {
298 char *hostName = hostutil_GetNameByINet(hosts[j]);
300 resultFiles.Add(StripPath(files[i]));
303 resultFiles.Add(" ");
304 servers.Add(hostName);
308 LoadString (str, IDS_SHOW_FS);
309 LoadString (str2, IDS_SHOW_FS_COLUMN);
310 CResultsDlg dlg(SHOW_FILE_SERVERS_HELP_ID);
311 dlg.SetContents(str, str2, resultFiles, servers);
316 CMtoUNIXerror(int cm_code)
319 case CM_ERROR_TIMEDOUT:
321 case CM_ERROR_NOACCESS:
323 case CM_ERROR_NOSUCHFILE:
329 case CM_ERROR_EXISTS:
331 case CM_ERROR_CROSSDEVLINK:
333 case CM_ERROR_NOTDIR:
337 case CM_ERROR_READONLY:
339 case CM_ERROR_WOULDBLOCK:
341 case CM_ERROR_NOSUCHCELL:
342 return ESRCH; /* hack */
343 case CM_ERROR_NOSUCHVOLUME:
344 return EPIPE; /* hack */
345 case CM_ERROR_NOMORETOKENS:
346 return EDOM; /* hack */
347 case CM_ERROR_TOOMANYBUFS:
348 return EFBIG; /* hack */
350 if (cm_code > 0 && cm_code < EILSEQ)
357 CString GetAfsError(int code, const char *filename)
361 code = CMtoUNIXerror(code);
363 if (code == EINVAL) {
365 strMsg.Format("Invalid argument; it is possible that the file is not in AFS");
367 strMsg.Format("Invalid argument");
368 } else if (code == ENOENT) {
370 strMsg.Format("The file does not exist");
372 strMsg.Format("No such file returned");
373 } else if (code == EROFS) {
374 strMsg.Format("You can not change a backup or readonly volume");
375 } else if (code == EACCES || code == EPERM) {
376 strMsg.Format("You do not have the required rights to do this operation");
377 } else if (code == ENODEV) {
378 strMsg.Format("AFS service may not have started");
379 } else if (code == ESRCH) {
380 strMsg.Format("Cell name not recognized");
381 } else if (code == ETIMEDOUT) {
382 strMsg.Format("Connection timed out");
383 } else if (code == EPIPE) {
384 strMsg.Format("Volume name or ID not recognized");
386 strMsg.Format("Error 0x%x occurred", code);
393 /************************************************************************
394 ************************** ACL Code *************************************
395 ************************************************************************/
397 typedef char sec_rgy_name_t[1025]; /* A DCE definition */
400 struct AclEntry *next;
406 int dfs; // Originally true if a dfs acl; now also the type
407 // of the acl (1, 2, or 3, corresponding to object,
408 // initial dir, or initial object).
409 sec_rgy_name_t cell; // DFS cell name
412 struct AclEntry *pluslist;
413 struct AclEntry *minuslist;
416 int foldcmp (register char *a, register char *b)
422 if (t >= 'A' && t <= 'Z') t += 0x20;
423 if (u >= 'A' && u <= 'Z') u += 0x20;
424 if (t != u) return 1;
425 if (t == 0) return 0;
429 extern "C" void ZapList(struct AclEntry *alist)
431 register struct AclEntry *tp, *np;
433 for (tp = alist; tp; tp = np) {
439 extern "C" void ZapAcl (struct Acl *acl)
441 ZapList(acl->pluslist);
442 ZapList(acl->minuslist);
446 extern "C" int PruneList (struct AclEntry **ae, int dfs)
448 struct AclEntry **lp = ae;
449 struct AclEntry *te, *ne;
452 for (te = *ae; te; te = ne) {
453 if ((!dfs && te->rights == 0) || te->rights == -1) {
468 char *SkipLine (register char *astr)
470 while (*astr != '\n')
478 /* tell if a name is 23 or -45 (digits or minus digits), which are bad names we must prune */
479 static int BadName(register char *aname)
483 /* all must be '-' or digit to be bad */
484 while (tc = *aname++) {
485 if ((tc != '-') && (tc < '0' || tc > '9'))
492 CString GetRightsString(register LONG arights, int dfs)
497 if (arights & PRSFS_READ) str += "r";
498 if (arights & PRSFS_LOOKUP) str += "l";
499 if (arights & PRSFS_INSERT) str += "i";
500 if (arights & PRSFS_DELETE) str += "d";
501 if (arights & PRSFS_WRITE) str += "w";
502 if (arights & PRSFS_LOCK) str += "k";
503 if (arights & PRSFS_ADMINISTER) str += "a";
507 if (arights & DFS_READ) str += "r"; else str += "-";
508 if (arights & DFS_WRITE) str += "w"; else printf("-");
509 if (arights & DFS_EXECUTE) str += "x"; else printf("-");
510 if (arights & DFS_CONTROL) str += "c"; else printf("-");
511 if (arights & DFS_INSERT) str += "i"; else printf("-");
512 if (arights & DFS_DELETE) str += "d"; else printf("-");
513 if (arights & (DFS_USRALL)) str += "+";
520 char *AclToString(struct Acl *acl)
522 static char mydata[MAXSIZE];
523 char tstring[MAXSIZE];
528 sprintf(dfsstring, " dfs:%d %s", acl->dfs, acl->cell);
531 sprintf(mydata, "%d%s\n%d\n", acl->nplus, dfsstring, acl->nminus);
533 for(tp = acl->pluslist; tp; tp = tp->next) {
534 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
535 strcat(mydata, tstring);
538 for(tp = acl->minuslist; tp; tp = tp->next) {
539 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
540 strcat(mydata, tstring);
546 struct Acl *EmptyAcl(const CString& strCellName)
548 register struct Acl *tp;
550 tp = (struct Acl *)malloc(sizeof (struct Acl));
551 tp->nplus = tp->nminus = 0;
552 tp->pluslist = tp->minuslist = 0;
554 strcpy(tp->cell, strCellName);
559 struct Acl *ParseAcl(char *astr)
561 int nplus, nminus, i, trights;
563 struct AclEntry *first, *last, *tl;
566 ta = (struct Acl *) malloc (sizeof (struct Acl));
568 sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
569 astr = SkipLine(astr);
570 sscanf(astr, "%d", &ta->nminus);
571 astr = SkipLine(astr);
578 for(i = 0; i < nplus; i++) {
579 sscanf(astr, "%100s %d", tname, &trights);
580 astr = SkipLine(astr);
581 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
584 strcpy(tl->name, tname);
585 tl->rights = trights;
591 ta->pluslist = first;
595 for(i=0; i < nminus; i++) {
596 sscanf(astr, "%100s %d", tname, &trights);
597 astr = SkipLine(astr);
598 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
601 strcpy(tl->name, tname);
602 tl->rights = trights;
608 ta->minuslist = first;
613 /* clean up an access control list of its bad entries; return 1 if we made
614 any changes to the list, and 0 otherwise */
615 extern "C" int CleanAcl(struct Acl *aa)
617 register struct AclEntry *te, **le, *ne;
622 /* Don't correct DFS ACL's for now */
626 /* prune out bad entries */
627 changes = 0; /* count deleted entries */
629 for(te = aa->pluslist; te; te = ne) {
631 if (BadName(te->name)) {
644 for(te = aa->minuslist; te; te = ne) {
646 if (BadName(te->name)) {
660 void CleanACL(CStringArray& names)
663 register struct Acl *ta;
664 struct ViceIoctl blob;
667 ShowMessageBox(IDS_CLEANACL_MSG, MB_OK|MB_ICONINFORMATION, IDS_CLEANACL_MSG);
671 for (int i = 0; i < names.GetSize(); i++) {
672 blob.out_size = MAXSIZE;
676 code = pioctl(PCCHAR(names[i]), VIOCGETAL, &blob, 1);
678 ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONERROR, 0, names[i], GetAfsError(errno));
682 ta = ParseAcl(space);
684 ShowMessageBox(IDS_CLEANACL_NOT_SUPPORTED, MB_ICONERROR, IDS_CLEANACL_NOT_SUPPORTED, names[i]);
688 changes = CleanAcl(ta);
692 /* now set the acl */
693 blob.in = AclToString(ta);
694 blob.in_size = strlen((char *)blob.in) + 1;
697 code = pioctl(PCCHAR(names[i]), VIOCSETAL, &blob, 1);
699 if (errno == EINVAL) {
700 ShowMessageBox(IDS_CLEANACL_INVALID_ARG, MB_ICONERROR, IDS_CLEANACL_INVALID_ARG, names[i]);
704 ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONERROR, 0, names[i], GetAfsError(errno));
711 // Derived from fs.c's ListAclCmd
712 BOOL GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& strNegative)
715 register struct Acl *ta;
716 struct ViceIoctl blob;
718 int idf = 0; //getidf(as, parm_listacl_id);
722 blob.out_size = MAXSIZE;
724 blob.in = blob.out = space;
726 code = pioctl(PCCHAR(strDir), VIOCGETAL, &blob, 1);
728 ShowMessageBox(IDS_GETRIGHTS_ERROR, MB_ICONERROR, IDS_GETRIGHTS_ERROR, strDir, GetAfsError(errno));
732 ta = ParseAcl(space);
734 ShowMessageBox(IDS_DFSACL_ERROR, MB_ICONERROR, IDS_DFSACL_ERROR);
739 // printf(" Default cell = %s\n", ta->cell);
744 for (te = ta->pluslist; te; te = te->next) {
745 strNormal.Add(te->name);
746 strNormal.Add(GetRightsString(te->rights, ta->dfs));
750 if (ta->nminus > 0) {
751 for (te = ta->minuslist; te; te = te->next) {
752 strNegative.Add(te->name);
753 strNegative.Add(GetRightsString(te->rights, ta->dfs));
760 struct AclEntry *FindList(register struct AclEntry *pCurEntry, const char *entryName)
763 if (!foldcmp(pCurEntry->name, PCCHAR(entryName)))
765 pCurEntry = pCurEntry->next;
771 void ChangeList (struct Acl *pAcl, BYTE bNormalRights, const char *entryName, LONG nEntryRights)
776 struct AclEntry *pEntry;
780 pEntry = (bNormalRights ? pAcl->pluslist : pAcl->minuslist);
781 pEntry = FindList(pEntry, entryName);
783 /* Found the item already in the list. */
785 pEntry->rights = nEntryRights;
787 pAcl->nplus -= PruneList(&pAcl->pluslist, pAcl->dfs);
789 pAcl->nminus -= PruneList(&pAcl->minuslist, pAcl->dfs);
793 /* Otherwise we make a new item and plug in the new data. */
794 pEntry = (struct AclEntry *) malloc(sizeof (struct AclEntry));
797 strcpy(pEntry->name, entryName);
798 pEntry->rights = nEntryRights;
801 pEntry->next = pAcl->pluslist;
802 pAcl->pluslist = pEntry;
804 if (nEntryRights == 0 || nEntryRights == -1)
805 pAcl->nplus -= PruneList(&pAcl->pluslist, pAcl->dfs);
808 pEntry->next = pAcl->minuslist;
809 pAcl->minuslist = pEntry;
811 if (nEntryRights == 0)
812 pAcl->nminus -= PruneList(&pAcl->minuslist, pAcl->dfs);
816 enum rtype {add, destroy, deny};
818 LONG Convert(const register char *arights, int dfs, enum rtype *rtypep)
824 *rtypep = add; /* add rights, by default */
826 if (!strcmp(arights,"read"))
827 return PRSFS_READ | PRSFS_LOOKUP;
828 if (!strcmp(arights, "write"))
829 return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
830 if (!strcmp(arights, "mail"))
831 return PRSFS_INSERT | PRSFS_LOCK | PRSFS_LOOKUP;
832 if (!strcmp(arights, "all"))
833 return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
835 if (!strcmp(arights, "none")) {
836 *rtypep = destroy; /* Remove entire entry */
840 len = strlen(arights);
843 for (i = 0; i < len; i++) {
845 if (tc == 'r') mode |= PRSFS_READ;
846 else if (tc == 'l') mode |= PRSFS_LOOKUP;
847 else if (tc == 'i') mode |= PRSFS_INSERT;
848 else if (tc == 'd') mode |= PRSFS_DELETE;
849 else if (tc == 'w') mode |= PRSFS_WRITE;
850 else if (tc == 'k') mode |= PRSFS_LOCK;
851 else if (tc == 'a') mode |= PRSFS_ADMINISTER;
853 fprintf(stderr, "illegal rights character '%c'.\n", tc);
860 BOOL SaveACL(const CString& strCellName, const CString& strDir, const CStringArray& normal, const CStringArray& negative)
863 struct ViceIoctl blob;
871 pAcl = EmptyAcl(strCellName);
873 // Set its normal rights
875 for (i = 0; i < normal.GetSize(); i += 2) {
876 rights = Convert(normal[i + 1], 0, &rtype);
877 ChangeList(pAcl, TRUE, normal[i], rights);
880 // Set its negative rights
881 for (i = 0; i < negative.GetSize(); i += 2) {
882 rights = Convert(negative[i + 1], 0, &rtype);
883 ChangeList(pAcl, FALSE, negative[i], rights);
887 blob.in = AclToString(pAcl);
889 blob.in_size = 1 + strlen((const char *)blob.in);
891 code = pioctl(PCCHAR(strDir), VIOCSETAL, &blob, 1);
894 ShowMessageBox(IDS_SAVE_ACL_EINVAL_ERROR, MB_ICONERROR, IDS_SAVE_ACL_EINVAL_ERROR, strDir);
896 ShowMessageBox(IDS_SAVE_ACL_ERROR, MB_ICONERROR, IDS_SAVE_ACL_ERROR, strDir, GetAfsError(errno, strDir));
904 BOOL CopyACL(const CString& strToDir, const CStringArray& normal, const CStringArray& negative, BOOL bClear)
907 struct ViceIoctl blob;
909 int idf = 0; // getidf(as, parm_copyacl_id);
913 // Get ACL to copy to
914 blob.out_size = MAXSIZE;
916 blob.in = blob.out = space;
918 code = pioctl(PCCHAR(strToDir), VIOCGETAL, &blob, 1);
920 ShowMessageBox(IDS_ACL_READ_ERROR, MB_ICONERROR, IDS_ACL_READ_ERROR, strToDir, GetAfsError(errno, strToDir));
925 pToAcl = EmptyAcl(space);
927 pToAcl = ParseAcl(space);
932 ShowMessageBox(IDS_NO_DFS_COPY_ACL, MB_ICONERROR, IDS_NO_DFS_COPY_ACL, strToDir);
941 for (i = 0; i < normal.GetSize(); i += 2) {
942 LONG rights = Convert(normal[i + 1], 0, &rtype);
943 ChangeList(pToAcl, TRUE, normal[i], rights);
946 // Set negative rights
947 for (i = 0; i < negative.GetSize(); i += 2) {
948 LONG rights = Convert(negative[i + 1], 0, &rtype);
949 ChangeList(pToAcl, FALSE, normal[i], rights);
953 blob.in = AclToString(pToAcl);
955 blob.in_size = 1 + strlen((char *)blob.in);
957 code = pioctl(PCCHAR(strToDir), VIOCSETAL, &blob, 1);
961 ShowMessageBox(IDS_COPY_ACL_EINVAL_ERROR, MB_ICONERROR, IDS_COPY_ACL_EINVAL_ERROR, strToDir);
963 ShowMessageBox(IDS_COPY_ACL_ERROR, MB_ICONERROR, IDS_COPY_ACL_ERROR, strToDir, GetAfsError(errno, strToDir));
969 ShowMessageBox(IDS_COPY_ACL_OK, MB_OK|MB_ICONINFORMATION, IDS_COPY_ACL_OK);
974 CString ParseMountPoint(const CString strFile, CString strMountPoint)
979 CString strMountPointInfo;
981 if (strMountPoint[0] == '#')
983 else if (strMountPoint[0] == '%')
984 strType = "Read/Write";
986 int nColon = strMountPoint.Find(':');
988 strCell = strMountPoint.Mid(1, nColon - 1);
989 strVolume = strMountPoint.Mid(nColon + 1);
991 strVolume = strMountPoint.Mid(1);
993 strMountPointInfo = strFile + "\t" + strVolume + "\t" + strCell + "\t" + strType;
995 return strMountPointInfo;
998 BOOL IsPathInAfs(const CHAR *strPath)
1000 struct ViceIoctl blob;
1003 HOURGLASS hourglass;
1006 blob.out_size = MAXSIZE;
1009 code = pioctl((LPTSTR)((LPCTSTR)strPath), VIOC_FILE_CELL_NAME, &blob, 1);
1016 IsFreelanceRoot(char *apath)
1018 struct ViceIoctl blob;
1022 blob.out_size = MAXSIZE;
1025 code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
1027 return !strcmp("Freelance.Local.Root",space);
1028 return 1; /* assume it is because it is more restrictive that way */
1031 const char * NetbiosName(void)
1033 static char buffer[1024] = "AFS";
1039 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
1040 0, KEY_QUERY_VALUE, &parmKey);
1041 if (code == ERROR_SUCCESS) {
1042 dummyLen = sizeof(buffer);
1043 code = RegQueryValueEx(parmKey, "NetbiosName", NULL, NULL,
1044 (LPBYTE)buffer, &dummyLen);
1045 RegCloseKey (parmKey);
1047 strcpy(buffer, "AFS");
1052 #define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins"
1054 static BOOL IsAdmin (void)
1056 static BOOL fAdmin = FALSE;
1057 static BOOL fTested = FALSE;
1061 /* Obtain the SID for the AFS client admin group. If the group does
1062 * not exist, then assume we have AFS client admin privileges.
1064 PSID psidAdmin = NULL;
1065 DWORD dwSize, dwSize2;
1066 char pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ];
1067 char *pszRefDomain = NULL;
1068 SID_NAME_USE snu = SidTypeGroup;
1070 dwSize = sizeof(pszAdminGroup);
1072 if (!GetComputerName(pszAdminGroup, &dwSize)) {
1073 /* Can't get computer name. We return false in this case.
1074 Retain fAdmin and fTested. This shouldn't happen.*/
1081 strcat(pszAdminGroup,"\\");
1082 strcat(pszAdminGroup, AFSCLIENT_ADMIN_GROUPNAME);
1084 LookupAccountName(NULL, pszAdminGroup, NULL, &dwSize, NULL, &dwSize2, &snu);
1085 /* that should always fail. */
1087 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
1088 /* if we can't find the group, then we allow the operation */
1093 if (dwSize == 0 || dwSize2 == 0) {
1099 psidAdmin = (PSID)malloc(dwSize); memset(psidAdmin,0,dwSize);
1100 pszRefDomain = (char *)malloc(dwSize2);
1102 if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) {
1103 /* We can't lookup the group now even though we looked it up earlier.
1104 Could this happen? */
1107 /* Then open our current ProcessToken */
1110 if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken))
1113 if (!CheckTokenMembership(hToken, psidAdmin, &fAdmin)) {
1114 /* We'll have to allocate a chunk of memory to store the list of
1115 * groups to which this user belongs; find out how much memory
1119 PTOKEN_GROUPS pGroups;
1121 GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize);
1123 pGroups = (PTOKEN_GROUPS)malloc(dwSize);
1125 /* Allocate that buffer, and read in the list of groups. */
1126 if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize))
1128 /* Look through the list of group SIDs and see if any of them
1129 * matches the AFS Client Admin group SID.
1132 for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup)
1134 if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) {
1144 /* if do not have permission because we were not explicitly listed
1145 * in the Admin Client Group let's see if we are the SYSTEM account
1148 PTOKEN_USER pTokenUser;
1149 SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
1150 PSID pSidLocalSystem = 0;
1153 GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
1155 pTokenUser = (PTOKEN_USER)malloc(dwSize);
1157 if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize))
1158 gle = GetLastError();
1160 if (AllocateAndInitializeSid( &SIDAuth, 1,
1161 SECURITY_LOCAL_SYSTEM_RID,
1162 0, 0, 0, 0, 0, 0, 0,
1165 if (EqualSid(pTokenUser->User.Sid, pSidLocalSystem)) {
1169 FreeSid(pSidLocalSystem);
1187 /* return a static pointer to a buffer */
1188 static char *Parent(char *apath)
1192 strcpy(tspace, apath);
1193 tp = strrchr(tspace, '\\');
1195 *(tp+1) = 0; /* lv trailing slash so Parent("k:\foo") is "k:\" not "k:" */
1198 fs_ExtractDriveLetter(apath, tspace);
1199 strcat(tspace, ".");
1206 GetCell(char *fname, char *cellname)
1209 struct ViceIoctl blob;
1212 blob.out_size = MAXCELLCHARS;
1213 blob.out = cellname;
1215 code = pioctl(fname, VIOC_FILE_CELL_NAME, &blob, 1);
1216 return code ? errno : 0;
1220 BOOL ListMount(CStringArray& files)
1223 struct ViceIoctl blob;
1225 char orig_name[1024]; /* Original name, may be modified */
1226 char true_name[1024]; /* ``True'' dirname (e.g., symlink target) */
1227 char parent_dir[1024]; /* Parent directory of true name */
1228 register char *last_component; /* Last component of true name */
1229 CStringArray mountPoints;
1231 HOURGLASS hourglass;
1235 for (int i = 0; i < files.GetSize(); i++) {
1236 strcpy(orig_name, files[i]);
1237 strcpy(true_name, orig_name);
1240 * Find rightmost slash, if any.
1242 last_component = (char *)strrchr(true_name, '\\');
1243 if (last_component) {
1245 * Found it. Designate everything before it as the parent directory,
1246 * everything after it as the final component.
1248 strncpy(parent_dir, true_name, last_component - true_name + 1);
1249 parent_dir[last_component - true_name + 1] = 0;
1250 last_component++; /* Skip the slash */
1252 if (!IsPathInAfs(parent_dir)) {
1253 const char * nbname = NetbiosName();
1254 int len = strlen(nbname);
1256 if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
1257 parent_dir[len+2] == '\\' &&
1258 parent_dir[len+3] == '\0' &&
1259 !strnicmp(nbname,&parent_dir[2],len))
1261 sprintf(parent_dir,"\\\\%s\\all\\", nbname);
1267 * No slash appears in the given file name. Set parent_dir to the current
1268 * directory, and the last component as the given name.
1270 fs_ExtractDriveLetter(true_name, parent_dir);
1271 strcat(parent_dir, ".");
1272 last_component = true_name;
1273 fs_StripDriveLetter(true_name, true_name, sizeof(true_name));
1276 blob.in = last_component;
1277 blob.in_size = strlen(last_component) + 1;
1278 blob.out_size = MAXSIZE;
1280 memset(space, 0, MAXSIZE);
1282 code = pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
1284 int nPos = strlen(space) - 1;
1285 if (space[nPos] == '.')
1287 mountPoints.Add(ParseMountPoint(StripPath(files[i]), space));
1290 if (errno == EINVAL)
1291 mountPoints.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(files[i])));
1293 mountPoints.Add(GetMessageString(IDS_LIST_MOUNT_POINT_ERROR, GetAfsError(errno, StripPath(files[i]))));
1297 CMountPointsDlg dlg;
1298 dlg.SetMountPoints(mountPoints);
1304 BOOL MakeMount(const CString& strDir, const CString& strVolName, const CString& strCellName, BOOL bRW)
1307 register char *cellName;
1308 char localCellName[128];
1309 struct afsconf_cell info;
1311 struct vldbentry vldbEntry;
1313 struct ViceIoctl blob;
1315 char path[1024] = "";
1317 HOURGLASS hourglass;
1319 ASSERT(strVolName.GetLength() < 64);
1321 if (strCellName.GetLength() > 0) /* cell name specified */
1322 cellName = PCCHAR(strCellName);
1324 cellName = (char *) 0;
1326 parent = Parent(PCCHAR(strDir));
1327 if (!IsPathInAfs(parent)) {
1328 const char * nbname = NetbiosName();
1329 int len = strlen(nbname);
1331 if (parent[0] == '\\' && parent[1] == '\\' &&
1332 parent[len+2] == '\\' &&
1333 parent[len+3] == '\0' &&
1334 !strnicmp(nbname,&parent[2],len))
1336 sprintf(path,"%sall\\%s", parent, &(PCCHAR(strDir)[strlen(parent)]));
1337 parent = Parent(path);
1338 if (!IsPathInAfs(parent)) {
1339 ShowMessageBox(IDS_MAKE_MP_NOT_AFS_ERROR, MB_ICONERROR, IDS_MAKE_MP_NOT_AFS_ERROR);
1343 ShowMessageBox(IDS_MAKE_MP_NOT_AFS_ERROR, MB_ICONERROR, IDS_MAKE_MP_NOT_AFS_ERROR);
1348 if ( strlen(path) == 0 )
1349 strcpy(path, PCCHAR(strDir));
1351 if ( IsFreelanceRoot(parent) ) {
1353 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
1359 blob.out_size = sizeof(localCellName);
1360 blob.out = localCellName;
1361 code = pioctl(parent, VIOC_GET_WS_CELL, &blob, 1);
1363 cellName = localCellName;
1367 GetCell(parent,space);
1370 code = GetCellName(cellName?cellName:space, &info);
1376 code = VLDBInit(1, &info);
1378 /* make the check. Don't complain if there are problems with init */
1379 code = ubik_VL_GetEntryByNameO(uclient, 0, PCCHAR(strVolName), &vldbEntry);
1380 if (code == VL_NOENT) {
1381 ShowMessageBox(IDS_WARNING, MB_ICONWARNING, IDS_VOLUME_NOT_IN_CELL_WARNING,
1382 PCCHAR(strVolName), cellName ? cellName : space);
1389 if (bRW) /* if -rw specified */
1394 /* If cellular mount point, prepend cell prefix */
1396 strcat(space, info.name);
1400 strcat(space, strVolName); /* append volume name */
1401 strcat(space, "."); /* stupid convention; these end with a period */
1403 /* create symlink with a special pioctl for Windows NT, since it doesn't
1404 * have a symlink system call.
1407 blob.in_size = 1 + strlen(space);
1410 code = pioctl(path, VIOC_AFS_CREATE_MT_PT, &blob, 0);
1413 ShowMessageBox(IDS_MOUNT_POINT_ERROR, MB_ICONERROR, IDS_MOUNT_POINT_ERROR, GetAfsError(errno, strDir));
1422 long fs_ExtractDriveLetter(const char *inPathp, char *outPathp)
1424 if (inPathp[0] != 0 && inPathp[1] == ':') {
1425 /* there is a drive letter */
1426 *outPathp++ = *inPathp++;
1427 *outPathp++ = *inPathp++;
1435 /* strip the drive letter from a component */
1436 long fs_StripDriveLetter(const char *inPathp, char *outPathp, long outSize)
1438 char tempBuffer[1000];
1439 strcpy(tempBuffer, inPathp);
1440 if (tempBuffer[0] != 0 && tempBuffer[1] == ':') {
1441 /* drive letter present */
1442 strcpy(outPathp, tempBuffer+2);
1445 /* no drive letter present */
1446 strcpy(outPathp, tempBuffer);
1452 BOOL RemoveSymlink(const char * linkName)
1456 struct ViceIoctl blob;
1458 char lsbuffer[1024];
1459 char tpbuffer[1024];
1462 HOURGLASS hourglass;
1464 tp = (char *) strrchr(linkName, '\\');
1466 tp = (char *) strrchr(linkName, '/');
1468 strncpy(tbuffer, linkName, code=tp-linkName+1); /* the dir name */
1470 tp++; /* skip the slash */
1472 if (!IsPathInAfs(tbuffer)) {
1473 const char * nbname = NetbiosName();
1474 int len = strlen(nbname);
1476 if (tbuffer[0] == '\\' && tbuffer[1] == '\\' &&
1477 tbuffer[len+2] == '\\' &&
1478 tbuffer[len+3] == '\0' &&
1479 !strnicmp(nbname,&tbuffer[2],len))
1481 sprintf(tbuffer,"\\\\%s\\all\\", nbname);
1486 fs_ExtractDriveLetter(linkName, tbuffer);
1487 strcat(tbuffer, ".");
1488 fs_StripDriveLetter(tp, tpbuffer, 0);
1492 if ( IsFreelanceRoot(tbuffer) && !IsAdmin() ) {
1493 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
1498 blob.in_size = strlen(tp)+1;
1499 blob.out = lsbuffer;
1500 blob.out_size = sizeof(lsbuffer);
1501 code = pioctl(tbuffer, VIOC_LISTSYMLINK, &blob, 0);
1506 blob.in_size = strlen(tp)+1;
1507 return (pioctl(tbuffer, VIOC_DELSYMLINK, &blob, 0)==0);
1510 BOOL IsSymlink(const char * true_name)
1512 char parent_dir[MAXSIZE]; /*Parent directory of true name*/
1513 char strip_name[MAXSIZE];
1514 struct ViceIoctl blob;
1515 char *last_component;
1518 HOURGLASS hourglass;
1520 last_component = (char *) strrchr(true_name, '\\');
1521 if (!last_component)
1522 last_component = (char *) strrchr(true_name, '/');
1523 if (last_component) {
1525 * Found it. Designate everything before it as the parent directory,
1526 * everything after it as the final component.
1528 strncpy(parent_dir, true_name, last_component - true_name + 1);
1529 parent_dir[last_component - true_name + 1] = 0;
1530 last_component++; /*Skip the slash*/
1532 if (!IsPathInAfs(parent_dir)) {
1533 const char * nbname = NetbiosName();
1534 int len = strlen(nbname);
1536 if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
1537 parent_dir[len+2] == '\\' &&
1538 parent_dir[len+3] == '\0' &&
1539 !strnicmp(nbname,&parent_dir[2],len))
1541 sprintf(parent_dir,"\\\\%s\\all\\", nbname);
1547 * No slash appears in the given file name. Set parent_dir to the current
1548 * directory, and the last component as the given name.
1550 fs_ExtractDriveLetter(true_name, parent_dir);
1551 strcat(parent_dir, ".");
1552 last_component = strip_name;
1553 fs_StripDriveLetter(true_name, strip_name, sizeof(strip_name));
1556 blob.in = last_component;
1557 blob.in_size = strlen(last_component)+1;
1558 blob.out_size = MAXSIZE;
1560 memset(space, 0, MAXSIZE);
1561 code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1);
1566 BOOL IsMountPoint(const char * name)
1568 register LONG code = 0;
1569 struct ViceIoctl blob;
1571 char lsbuffer[1024];
1573 char szCurItem[1024];
1575 strcpy(szCurItem, name);
1577 tp = (char *)strrchr(szCurItem, '\\');
1579 strncpy(tbuffer, szCurItem, code = tp - szCurItem + 1); /* the dir name */
1581 tp++; /* skip the slash */
1583 if (!IsPathInAfs(tbuffer)) {
1584 const char * nbname = NetbiosName();
1585 int len = strlen(nbname);
1587 if (tbuffer[0] == '\\' && tbuffer[1] == '\\' &&
1588 tbuffer[len+2] == '\\' &&
1589 tbuffer[len+3] == '\0' &&
1590 !strnicmp(nbname,&tbuffer[2],len))
1592 sprintf(tbuffer,"\\\\%s\\all\\", nbname);
1596 fs_ExtractDriveLetter(szCurItem, tbuffer);
1597 strcat(tbuffer, ".");
1599 fs_StripDriveLetter(tp, tp, 0);
1603 blob.in_size = strlen(tp)+1;
1604 blob.out = lsbuffer;
1605 blob.out_size = sizeof(lsbuffer);
1607 code = pioctl(tbuffer, VIOC_AFS_STAT_MT_PT, &blob, 0);
1614 * Delete AFS mount points. Variables are used as follows:
1615 * tbuffer: Set to point to the null-terminated directory name of the mount point
1616 * (or ``.'' if none is provided)
1617 * tp: Set to point to the actual name of the mount point to nuke.
1619 BOOL RemoveMount(CStringArray& files)
1621 register LONG code = 0;
1622 struct ViceIoctl blob;
1625 char szCurItem[1024];
1627 CStringArray results;
1631 HOURGLASS hourglass;
1633 for (int i = 0; i < files.GetSize(); i++) {
1634 if (!IsMountPoint(files[i])) {
1636 if (errno == EINVAL)
1637 results.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(files[i])));
1639 results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
1640 continue; // don't bother trying
1643 strcpy(szCurItem, files[i]);
1645 tp = (char *)strrchr(szCurItem, '\\');
1647 strncpy(tbuffer, szCurItem, code = tp - szCurItem + 1); /* the dir name */
1649 tp++; /* skip the slash */
1651 if (!IsPathInAfs(tbuffer)) {
1652 const char * nbname = NetbiosName();
1653 int len = strlen(nbname);
1655 if (tbuffer[0] == '\\' && tbuffer[1] == '\\' &&
1656 tbuffer[len+2] == '\\' &&
1657 tbuffer[len+3] == '\0' &&
1658 !strnicmp(nbname,&tbuffer[2],len))
1660 sprintf(tbuffer,"\\\\%s\\all\\", nbname);
1664 fs_ExtractDriveLetter(szCurItem, tbuffer);
1665 strcat(tbuffer, ".");
1667 fs_StripDriveLetter(tp, tp, 0);
1670 if ( IsFreelanceRoot(tbuffer) && !IsAdmin() ) {
1671 results.Add(GetMessageString(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, StripPath(files[i])));
1673 continue; /* skip */
1678 blob.in_size = strlen(tp)+1;
1680 code = pioctl(tbuffer, VIOC_AFS_DELETE_MT_PT, &blob, 0);
1683 results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
1685 results.Add(GetMessageString(IDS_DELETED));
1688 LoadString (str, IDS_REMOVE_MP);
1689 LoadString (str2, IDS_REMOVE_MP_COLUMN);
1690 CResultsDlg dlg(REMOVE_MOUNT_POINTS_HELP_ID);
1691 dlg.SetContents(str, str2, StripPath(files), results);
1697 BOOL GetVolumeInfo(CString strFile, CVolInfo& volInfo)
1700 struct ViceIoctl blob;
1701 struct VolumeStatus *status;
1704 HOURGLASS hourglass;
1706 volInfo.m_strFilePath = strFile;
1707 volInfo.m_strFileName = StripPath(strFile);
1710 volInfo.m_strName = "VolumeName";
1712 volInfo.m_nQuota = 20 * 1024 * 1024;
1713 volInfo.m_nNewQuota = volInfo.m_nQuota;
1714 volInfo.m_nUsed = volInfo.m_nQuota / 2;
1715 volInfo.m_nPartSize = 50 * 1024 * 1024;
1716 volInfo.m_nPartFree = 30 * 1024 * 1024;
1717 volInfo.m_nDup = -1;
1721 blob.out_size = MAXSIZE;
1725 code = pioctl(PCCHAR(strFile), VIOCGETVOLSTAT, &blob, 1);
1727 volInfo.m_strErrorMsg = GetAfsError(errno, strFile);
1731 status = (VolumeStatus *)space;
1732 name = (char *)status + sizeof(*status);
1734 volInfo.m_strName = name;
1735 volInfo.m_nID = status->Vid;
1736 volInfo.m_nQuota = status->MaxQuota;
1737 volInfo.m_nNewQuota = status->MaxQuota;
1738 volInfo.m_nUsed = status->BlocksInUse;
1739 volInfo.m_nPartSize = status->PartMaxBlocks;
1740 volInfo.m_nPartFree = status->PartBlocksAvail;
1741 volInfo.m_nDup = -1;
1746 BOOL SetVolInfo(CVolInfo& volInfo)
1749 struct ViceIoctl blob;
1750 struct VolumeStatus *status;
1753 HOURGLASS hourglass;
1755 blob.out_size = MAXSIZE;
1756 blob.in_size = sizeof(*status) + 3; /* for the three terminating nulls */
1760 status = (VolumeStatus *)space;
1761 status->MinQuota = -1;
1762 status->MaxQuota = volInfo.m_nNewQuota;
1764 input = (char *)status + sizeof(*status);
1765 *(input++) = '\0'; /* never set name: this call doesn't change vldb */
1766 *(input++) = '\0'; // No offmsg
1767 *(input++) = '\0'; // No motd
1770 FILE *fp = OpenFile(szLogFileName, "a");
1772 fprintf(fp, "\nSetVolInfo() pioctl parms:\n");
1773 fprintf(fp, "\tpathp = %s\n\topcode = VIOCSETVOLSTAT (%d)\n\tblobp = %ld\n", PCCHAR(volInfo.m_strFilePath), VIOCSETVOLSTAT, &blob);
1774 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);
1775 fprintf(fp, "\t\t\tstatus->MinQuota = %ld\n", status->MinQuota);
1776 fprintf(fp, "\t\t\tstatus->MaxQuota = %ld\n", status->MaxQuota);
1777 fprintf(fp, "\t\t\tOther status fields aren't set\n");
1778 fprintf(fp, "\t\t\t3 nulls follow the VolumeStatus structure.\n");
1779 fprintf(fp, "\tfollow = 1\n");
1784 code = pioctl(PCCHAR(volInfo.m_strFilePath), VIOCSETVOLSTAT, &blob, 1);
1786 ShowMessageBox(IDS_SET_QUOTA_ERROR, MB_ICONERROR, IDS_SET_QUOTA_ERROR, GetAfsError(errno, volInfo.m_strName));
1793 int GetCellName(char *cellNamep, struct afsconf_cell *infop)
1795 strcpy(infop->name, cellNamep);
1799 BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast)
1802 struct ViceIoctl blob;
1805 struct afsconf_cell info;
1806 struct chservinfo checkserv;
1808 HOURGLASS hourglass;
1810 memset(&checkserv, 0, sizeof(struct chservinfo));
1811 blob.in_size = sizeof(struct chservinfo);
1812 blob.in = (caddr_t)&checkserv;
1814 blob.out_size = MAXSIZE;
1816 memset(space, 0, sizeof(afs_int32)); /* so we assure zero when nothing is copied back */
1818 if (nCellsToCheck == SPECIFIC_CELL) {
1820 GetCellName(PCCHAR(strCellName), &info);
1821 strcpy(checkserv.tbuffer,info.name);
1822 checkserv.tsize = strlen(info.name) + 1;
1824 if (nCellsToCheck != ALL_CELLS)
1826 strcpy(checkserv.tbuffer, "\0");
1827 checkserv.tsize = 0;
1830 temp |= 1; /* set fast flag */
1832 checkserv.magic = 0x12345678; /* XXX */
1833 checkserv.tflags = temp;
1834 checkserv.tinterval = -1; /* don't change current interval */
1836 code = pioctl(0, VIOCCKSERV, &blob, 1);
1838 ShowMessageBox(IDS_CHECK_SERVERS_ERROR, MB_ICONERROR, IDS_CHECK_SERVERS_ERROR, GetAfsError(errno, CString()));
1842 memcpy(&temp, space, sizeof(LONG));
1845 ShowMessageBox(IDS_ALL_SERVERS_RUNNING, MB_OK|MB_ICONINFORMATION, IDS_ALL_SERVERS_RUNNING);
1849 CStringArray servers;
1850 for (j = 0; j < MAXHOSTS; j++) {
1851 memcpy(&temp, space + j * sizeof(LONG), sizeof(LONG));
1855 char *name = hostutil_GetNameByINet(temp);
1859 CDownServersDlg dlg;
1860 dlg.SetServerNames(servers);
1866 BOOL GetTokenInfo(CStringArray& tokenInfo)
1870 time_t current_time;
1871 time_t tokenExpireTime;
1875 struct ktc_principal serviceName, clientName;
1876 struct ktc_token token;
1878 CString strTokenInfo;
1879 CString strUserName;
1880 CString strCellName;
1883 // tokenInfo.Add("");
1887 HOURGLASS hourglass;
1889 // printf("\nTokens held by the Cache Manager:\n\n");
1891 current_time = time(0);
1894 rc = ktc_ListTokens(cellNum, &cellNum, &serviceName);
1895 if (rc == KTC_NOENT) {
1897 // printf(" --End of list --\n");
1900 else if (rc == KTC_NOCM) {
1901 ShowMessageBox(IDS_GET_TOKENS_NO_AFS_SERVICE);
1902 // printf("AFS service may not have started\n");
1906 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR, MB_ICONERROR, IDS_GET_TOKENS_UNEXPECTED_ERROR, rc);
1908 // printf("Unexpected error, code %d\n", rc);
1912 rc = ktc_GetToken(&serviceName, &token, sizeof(token), &clientName);
1914 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR2, MB_ICONERROR, IDS_GET_TOKENS_UNEXPECTED_ERROR2,
1915 serviceName.name, serviceName.instance, serviceName.cell, rc);
1919 tokenExpireTime = token.endTime;
1921 strcpy(userName, clientName.name);
1922 if (clientName.instance[0] != 0) {
1923 strcat(userName, ".");
1924 strcat(userName, clientName.instance);
1927 BOOL bShowName = FALSE;
1929 if (userName[0] == '\0')
1930 ; //printf("Tokens");
1931 // AFS ID is not returned at this time.
1932 // else if (strncmp(userName, "AFS ID", 6) == 0)
1933 // printf("User's (%s) tokens", userName);
1934 // sscanf(userName, "(AFS ID %s)", szAfsID);
1935 else if (strncmp(userName, "Unix UID", 8) == 0)
1936 ; //printf("Tokens");
1938 strUserName = userName;
1939 // printf("User %s's tokens", userName);
1941 // printf(" for %s%s%s@%s ", serviceName.name, serviceName.instance[0] ? "." : "", serviceName.instance, serviceName.cell);
1942 strCellName = serviceName.cell;
1944 if (tokenExpireTime <= current_time)
1945 strExpir = "[>> Expired <<]";
1946 // printf("[>> Expired <<]\n");
1948 expireString = ctime(&tokenExpireTime);
1949 expireString += 4; /* Skip day of week */
1950 expireString[12] = '\0'; /* Omit secs & year */
1951 // printf("[Expires %s]\n", expireString);
1952 strExpir.Format("%s", expireString);
1955 strTokenInfo = strUserName + "\t" + strCellName + "\t" + strExpir + "\t" + strCellName;
1956 tokenInfo.Add(strTokenInfo);
1960 // printf("Press <Enter> or <Return> when finished: ");
1965 UINT MakeSymbolicLink(const char *strName, const char *strDir)
1967 struct ViceIoctl blob;
1968 char space[MAXSIZE];
1970 char path[1024] = "";
1973 HOURGLASS hourglass;
1974 static char message[2048];
1976 strcpy(path, strDir);
1977 parent = Parent(path);
1979 sprintf(message,"MakeSymbolicLink: path = %s parent = %s\n",path,parent);
1980 OutputDebugString(message);
1982 /*lets confirm its a good symlink*/
1983 if (!IsPathInAfs(path)) {
1984 const char * nbname = NetbiosName();
1985 int len = strlen(nbname);
1987 if (parent[0] == '\\' && parent[1] == '\\' &&
1988 parent[len+2] == '\\' &&
1989 parent[len+3] == '\0' &&
1990 !strnicmp(nbname,&parent[2],len))
1992 sprintf(path,"%sall\\%s", parent, &strDir[strlen(parent)]);
1993 parent = Parent(path);
1994 sprintf(message,"MakeSymbolicLink: new path = %s parent = %s\n",path,parent);
1995 OutputDebugString(message);
1997 if (!IsPathInAfs(parent)) {
1998 ShowMessageBox(IDS_MAKE_LNK_NOT_AFS_ERROR, MB_ICONERROR, IDS_MAKE_LNK_NOT_AFS_ERROR);
2002 ShowMessageBox(IDS_MAKE_LNK_NOT_AFS_ERROR, MB_ICONERROR, IDS_MAKE_LNK_NOT_AFS_ERROR);
2007 if ( IsFreelanceRoot(parent) && !IsAdmin() ) {
2008 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
2012 LPTSTR lpsz = new TCHAR[strlen(strDir)+1];
2013 _tcscpy(lpsz, strName);
2014 strcpy(space, strDir);
2016 blob.in_size = 1 + strlen(space);
2019 code=pioctl(lpsz, VIOC_SYMLINK, &blob, 0);
2026 void ListSymbolicLinkPath(const char *strName,char *strPath,UINT nlenPath)
2028 ASSERT(nlenPath<MAX_PATH);
2029 struct ViceIoctl blob;
2030 char orig_name[MAX_PATH+1]; /*Original name, may be modified*/
2031 char true_name[MAX_PATH+1]; /*``True'' dirname (e.g., symlink target)*/
2032 char parent_dir[MAX_PATH+1]; /*Parent directory of true name*/
2033 char *last_component; /*Last component of true name*/
2036 HOURGLASS hourglass;
2038 strcpy(orig_name, strName);
2039 strcpy(true_name, orig_name);
2041 * Find rightmost slash, if any.
2043 last_component = (char *) strrchr(true_name, '\\');
2044 if (!last_component)
2045 last_component = (char *) strrchr(true_name, '/');
2046 if (last_component) {
2048 * Found it. Designate everything before it as the parent directory,
2049 * everything after it as the final component.
2051 strncpy(parent_dir, true_name, last_component - true_name + 1);
2052 parent_dir[last_component - true_name + 1] = 0;
2053 last_component++; /*Skip the slash*/
2055 if (!IsPathInAfs(parent_dir)) {
2056 const char * nbname = NetbiosName();
2057 int len = strlen(nbname);
2059 if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
2060 parent_dir[len+2] == '\\' &&
2061 parent_dir[len+3] == '\0' &&
2062 !strnicmp(nbname,&parent_dir[2],len))
2064 sprintf(parent_dir,"\\\\%s\\all\\", nbname);
2070 * No slash appears in the given file name. Set parent_dir to the current
2071 * directory, and the last component as the given name.
2073 fs_ExtractDriveLetter(true_name, parent_dir);
2074 strcat(parent_dir, ".");
2075 last_component = true_name;
2076 fs_StripDriveLetter(true_name, true_name, sizeof(true_name));
2078 blob.in = last_component;
2079 blob.in_size = strlen(last_component)+1;
2080 blob.out_size = MAXSIZE;
2082 memset(space, 0, MAXSIZE);
2083 if ((code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1)))
2084 strcpy(space,"???");
2085 ASSERT(strlen(space)<MAX_PATH);
2086 strncpy(strPath,space,nlenPath);