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 <afsconfig.h>
16 #include <afs/param.h>
26 #include "results_dlg.h"
27 #include "volume_inf.h"
28 #include "mount_points_dlg.h"
29 #include "symlinks_dlg.h"
30 #include "hourglass.h"
31 #include "down_servers_dlg.h"
34 #include <rx/rx_globals.h>
37 #include <afs/afsint.h>
38 #include <afs/afs_consts.h>
39 #include <afs/cellconfig.h>
40 #include <afs/vldbint.h>
41 #include <afs/volser.h>
43 #include <WINNT\afsreg.h>
48 #include <cm_scache.h>
52 #define STRSAFE_NO_DEPRECATE
55 #define PCCHAR(str) ((char *)(const char *)(str))
56 #define VL_NOENT (363524L)
59 #define MAXINSIZE 1300 /* pioctl complains if data is larger than this */
60 #define VMSGSIZE 128 /* size of msg buf in volume hdr */
62 #define MAXCELLCHARS 64
63 #define MAXHOSTCHARS 64
64 #define MAXHOSTSPERCELL 8
66 static char space[AFS_PIOCTL_MAXSIZE];
67 static char tspace[1024];
69 static struct ubik_client *uclient;
70 static int rxInitDone = 0;
71 static char pn[] = "fs";
73 // #define LOGGING_ON // Enable this to log certain pioctl calls
76 static char *szLogFileName = "afsguilog.txt";
80 class CStringUtf8 : public CStringA
83 CStringUtf8(const CStringW& csw) : CStringA()
88 CStringUtf8(const char * cp) : CStringA(cp) {}
90 CStringUtf8() :CStringA() {}
92 void SetString(const CStringW& csw)
97 rv = WideCharToMultiByte(CP_UTF8, 0, csw, -1,
98 buffer, sizeof(buffer),
102 CStringA::SetString(buffer);
104 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
107 cb_req = WideCharToMultiByte(CP_UTF8, 0, csw, -1, NULL, 0, NULL, FALSE);
111 WideCharToMultiByte(CP_UTF8, 0, csw, -1, CStringA::GetBuffer(cb_req), cb_req, NULL, FALSE);
112 CStringA::ReleaseBuffer();
122 static CString _Utf8ToCString(const char * ustr)
127 cch = MultiByteToWideChar(CP_UTF8, 0, ustr, -1, NULL, 0);
134 cch = MultiByteToWideChar(CP_UTF8, 0, ustr, -1, cs.GetBuffer(cch), cch);
141 long pioctl_T(const CString& path, long opcode, struct ViceIoctl * blob, int follow)
143 CStringUtf8 upath(path);
145 return pioctl_utf8(PCCHAR(upath), opcode, blob, follow);
148 #define Utf8ToCString(cs) CStringUtf8::_Utf8ToCString(cs)
150 #define pioctl_T(path, op, vblob, follow) pioctl(PCCHAR(path), op, vblob, follow)
151 #define Utf8ToCString(cs) (cs)
157 VLDBInit(int noAuthFlag, struct afsconf_cell *info)
161 code = ugen_ClientInit(noAuthFlag, (char *)AFSDIR_CLIENT_ETC_DIRPATH,
162 info->name, 0, &uclient,
163 NULL, pn, rxkad_clear,
164 VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 50,
165 0, 0, USER_SERVICE_ID);
171 OpenFile(char *file, char *rwp)
178 code = GetWindowsDirectoryA(wdir, sizeof(wdir));
179 if (code == 0 || code > sizeof(wdir))
182 /* add trailing backslash, if required */
184 if (wdir[tlen - 1] != '\\')
189 fp = fopen(wdir, rwp);
194 CString StripPath(CString& strPath)
196 int nIndex = strPath.ReverseFind('\\');
198 CString strFile = strPath.Mid(nIndex + 1);
199 if (strFile.IsEmpty())
205 CStringArray& StripPath(CStringArray& files)
207 for (int i = 0; i < files.GetSize(); i++)
208 files[i] = StripPath(files[i]);
213 void Flush(const CStringArray& files)
216 struct ViceIoctl blob;
221 for (int i = 0; i < files.GetSize(); i++) {
222 blob.in_size = blob.out_size = 0;
224 code = pioctl_T(files[i], VIOCFLUSH, &blob, 0);
228 ShowMessageBox(IDS_FLUSH_FAILED, MB_ICONERROR, IDS_FLUSH_FAILED, files[i]);
230 ShowMessageBox(IDS_FLUSH_ERROR, MB_ICONERROR, IDS_FLUSH_ERROR, files[i], strerror(errno));
235 ShowMessageBox(IDS_FLUSH_OK, MB_ICONINFORMATION, IDS_FLUSH_OK);
238 void FlushVolume(const CStringArray& files)
241 struct ViceIoctl blob;
246 for (int i = 0; i < files.GetSize(); i++) {
247 blob.in_size = blob.out_size = 0;
249 code = pioctl_T(files[i], VIOC_FLUSHVOLUME, &blob, 0);
252 ShowMessageBox(IDS_FLUSH_VOLUME_ERROR, MB_ICONERROR, IDS_FLUSH_VOLUME_ERROR, files[i], strerror(errno));
257 ShowMessageBox(IDS_FLUSH_VOLUME_OK, MB_ICONINFORMATION, IDS_FLUSH_VOLUME_OK);
260 void WhichCell(CStringArray& files)
263 struct ViceIoctl blob;
268 CStringArray results;
274 for (int i = 0; i < files.GetSize(); i++) {
276 blob.out_size = AFS_PIOCTL_MAXSIZE;
279 code = pioctl_T(files[i], VIOC_FILE_CELL_NAME, &blob, 1);
281 if (code == ENOENT) {
282 LoadString (str, IDS_CANT_GET_CELL);
285 results.Add(GetAfsError(errno));
287 space[AFS_PIOCTL_MAXSIZE - 1] = '\0';
288 results.Add(Utf8ToCString(space));
292 LoadString (str, IDS_SHOW_CELL);
293 LoadString (str2, IDS_SHOW_CELL_COLUMN);
294 CResultsDlg dlg(SHOW_CELL_HELP_ID);
295 dlg.SetContents(str, str2, StripPath(files), results);
302 struct ViceIoctl blob;
307 blob.in = (char *) 0;
308 blob.out_size = AFS_PIOCTL_MAXSIZE;
311 code = pioctl((char *) 0, VIOC_GET_WS_CELL, &blob, 1);
314 //Die(errno, (char *) 0);
317 //printf("This workstation belongs to cell '%s'\n", space);
323 struct ViceIoctl blob;
327 code = pioctl(0, VIOCCKBACK, &blob, 1);
329 ShowMessageBox(IDS_CHECK_VOLUMES_ERROR, MB_ICONERROR, IDS_CHECK_VOLUMES_ERROR, GetAfsError(errno, CString()));
333 ShowMessageBox(IDS_CHECK_VOLUMES_OK, MB_OK|MB_ICONINFORMATION, IDS_CHECK_VOLUMES_OK);
338 void SetCacheSizeCmd(LONG nNewCacheSize)
341 struct ViceIoctl blob;
345 blob.in = (char *) &nNewCacheSize;
346 blob.in_size = sizeof(LONG);
349 code = pioctl(0, VIOCSETCACHESIZE, &blob, 1);
351 // Die(errno, (char *) 0);
353 // printf("New cache size set.\n");
356 void WhereIs(CStringArray& files)
359 struct ViceIoctl blob;
360 CStringArray servers;
361 CStringArray resultFiles;
367 for (int i = 0; i < files.GetSize(); i++) {
368 blob.out_size = AFS_PIOCTL_MAXSIZE;
371 memset(space, 0, sizeof(space));
373 code = pioctl_T(files[i], VIOCWHEREIS, &blob, 1);
375 resultFiles.Add(StripPath(files[i]));
376 servers.Add(GetAfsError(errno));
380 LONG *hosts = (LONG *)space;
384 for (int j = 0; j < AFS_MAXHOSTS; j++) {
387 char *hostName = hostutil_GetNameByINet(hosts[j]);
389 resultFiles.Add(StripPath(files[i]));
392 resultFiles.Add(" ");
393 servers.Add(hostName);
397 LoadString (str, IDS_SHOW_FS);
398 LoadString (str2, IDS_SHOW_FS_COLUMN);
399 CResultsDlg dlg(SHOW_FILE_SERVERS_HELP_ID);
400 dlg.SetContents(str, str2, resultFiles, servers);
405 CMtoUNIXerror(int cm_code)
408 case CM_ERROR_TIMEDOUT:
410 case CM_ERROR_NOACCESS:
412 case CM_ERROR_NOSUCHFILE:
418 case CM_ERROR_EXISTS:
420 case CM_ERROR_CROSSDEVLINK:
422 case CM_ERROR_NOTDIR:
426 case CM_ERROR_READONLY:
428 case CM_ERROR_WOULDBLOCK:
430 case CM_ERROR_NOSUCHCELL:
431 return ESRCH; /* hack */
432 case CM_ERROR_NOSUCHVOLUME:
433 return EPIPE; /* hack */
434 case CM_ERROR_NOMORETOKENS:
435 return EDOM; /* hack */
436 case CM_ERROR_TOOMANYBUFS:
437 return EFBIG; /* hack */
439 if (cm_code > 0 && cm_code < EILSEQ)
446 CString GetAfsError(int code, const TCHAR *filename)
450 code = CMtoUNIXerror(code);
452 if (code == EINVAL) {
454 strMsg.Format(_T("Invalid argument; it is possible that the file is not in AFS"));
456 strMsg.Format(_T("Invalid argument"));
457 } else if (code == ENOENT) {
459 strMsg.Format(_T("The file does not exist"));
461 strMsg.Format(_T("No such file returned"));
462 } else if (code == EROFS) {
463 strMsg.Format(_T("You can not change a backup or readonly volume"));
464 } else if (code == EACCES || code == EPERM) {
465 strMsg.Format(_T("You do not have the required rights to do this operation"));
466 } else if (code == ENODEV) {
467 strMsg.Format(_T("AFS service may not have started"));
468 } else if (code == ESRCH) {
469 strMsg.Format(_T("Cell name not recognized"));
470 } else if (code == ETIMEDOUT) {
471 strMsg.Format(_T("Connection timed out"));
472 } else if (code == EPIPE) {
473 strMsg.Format(_T("Volume name or ID not recognized"));
475 strMsg.Format(_T("Error 0x%x occurred"), code);
482 /************************************************************************
483 ************************** ACL Code *************************************
484 ************************************************************************/
486 typedef char sec_rgy_name_t[1025]; /* A DCE definition */
489 struct AclEntry *next;
495 int dfs; // Originally true if a dfs acl; now also the type
496 // of the acl (1, 2, or 3, corresponding to object,
497 // initial dir, or initial object).
498 sec_rgy_name_t cell; // DFS cell name
501 struct AclEntry *pluslist;
502 struct AclEntry *minuslist;
505 int foldcmp (char *a, char *b)
511 if (t >= 'A' && t <= 'Z') t += 0x20;
512 if (u >= 'A' && u <= 'Z') u += 0x20;
513 if (t != u) return 1;
514 if (t == 0) return 0;
518 extern "C" void ZapList(struct AclEntry *alist)
520 struct AclEntry *tp, *np;
522 for (tp = alist; tp; tp = np) {
528 extern "C" void ZapAcl (struct Acl *acl)
530 ZapList(acl->pluslist);
531 ZapList(acl->minuslist);
535 extern "C" int PruneList (struct AclEntry **ae, int dfs)
537 struct AclEntry **lp = ae;
538 struct AclEntry *te, *ne;
541 for (te = *ae; te; te = ne) {
542 if ((!dfs && te->rights == 0) || te->rights == -1) {
557 char *SkipLine (char *astr)
559 while (*astr != '\n')
567 /* tell if a name is 23 or -45 (digits or minus digits), which are bad names we must prune */
568 static int BadName(char *aname)
572 /* all must be '-' or digit to be bad */
573 while (tc = *aname++) {
574 if ((tc != '-') && (tc < '0' || tc > '9'))
581 CString GetRightsString(LONG arights, int dfs)
586 if (arights & PRSFS_READ) str += _T("r");
587 if (arights & PRSFS_LOOKUP) str += _T("l");
588 if (arights & PRSFS_INSERT) str += _T("i");
589 if (arights & PRSFS_DELETE) str += _T("d");
590 if (arights & PRSFS_WRITE) str += _T("w");
591 if (arights & PRSFS_LOCK) str += _T("k");
592 if (arights & PRSFS_ADMINISTER) str += _T("a");
596 if (arights & DFS_READ) str += _T("r"); else str += _T("-");
597 if (arights & DFS_WRITE) str += _T("w"); else printf(_T("-"));
598 if (arights & DFS_EXECUTE) str += _T("x"); else printf(_T("-"));
599 if (arights & DFS_CONTROL) str += _T("c"); else printf(_T("-"));
600 if (arights & DFS_INSERT) str += _T("i"); else printf(_T("-"));
601 if (arights & DFS_DELETE) str += _T("d"); else printf(_T("-"));
602 if (arights & (DFS_USRALL)) str += _T("+");
609 char *AclToString(struct Acl *acl)
611 static char mydata[AFS_PIOCTL_MAXSIZE];
612 char tstring[AFS_PIOCTL_MAXSIZE];
617 sprintf(dfsstring, " dfs:%d %s", acl->dfs, acl->cell);
620 sprintf(mydata, "%d%s\n%d\n", acl->nplus, dfsstring, acl->nminus);
622 for(tp = acl->pluslist; tp; tp = tp->next) {
623 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
624 strcat(mydata, tstring);
627 for(tp = acl->minuslist; tp; tp = tp->next) {
628 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
629 strcat(mydata, tstring);
635 struct Acl *EmptyAcl(const CString& strCellName)
638 CStringUtf8 ustrCell(strCellName);
640 tp = (struct Acl *)malloc(sizeof (struct Acl));
641 tp->nplus = tp->nminus = 0;
642 tp->pluslist = tp->minuslist = 0;
644 StringCbCopyA(tp->cell, sizeof(tp->cell), ustrCell);
649 struct Acl *EmptyAcl(char *astr)
654 tp = (struct Acl *)malloc(sizeof (struct Acl));
655 tp->nplus = tp->nminus = 0;
656 tp->pluslist = tp->minuslist = 0;
658 if (astr == NULL || sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell) <= 0) {
666 ParseAcl (char *astr)
668 int nplus, nminus, i, trights, ret;
670 struct AclEntry *first, *next, *last, *tl;
674 if (astr == NULL || strlen(astr) == 0)
677 ret = sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
682 astr = SkipLine(astr);
683 ret = sscanf(astr, "%d", &ta->nminus);
688 astr = SkipLine(astr);
695 for(i=0;i<nplus;i++) {
696 ret = sscanf(astr, "%100s %d", tname, &trights);
699 astr = SkipLine(astr);
700 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
705 strcpy(tl->name, tname);
706 tl->rights = trights;
712 ta->pluslist = first;
716 for(i=0;i<nminus;i++) {
717 ret = sscanf(astr, "%100s %d", tname, &trights);
720 astr = SkipLine(astr);
721 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
726 strcpy(tl->name, tname);
727 tl->rights = trights;
733 ta->minuslist = first;
738 for (;first; first = next) {
742 first = ta->pluslist;
745 for (;first; first = next) {
753 /* clean up an access control list of its bad entries; return 1 if we made
754 any changes to the list, and 0 otherwise */
755 extern "C" int CleanAcl(struct Acl *aa)
757 struct AclEntry *te, **le, *ne;
762 /* Don't correct DFS ACL's for now */
766 /* prune out bad entries */
767 changes = 0; /* count deleted entries */
769 for(te = aa->pluslist; te; te = ne) {
771 if (BadName(te->name)) {
784 for(te = aa->minuslist; te; te = ne) {
786 if (BadName(te->name)) {
800 void CleanACL(CStringArray& names)
804 struct ViceIoctl blob;
807 ShowMessageBox(IDS_CLEANACL_MSG, MB_OK|MB_ICONINFORMATION, IDS_CLEANACL_MSG);
811 for (int i = 0; i < names.GetSize(); i++) {
812 blob.out_size = AFS_PIOCTL_MAXSIZE;
816 code = pioctl_T(names[i], VIOCGETAL, &blob, 1);
818 ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONERROR, 0, names[i], GetAfsError(errno));
822 ta = ParseAcl(space);
824 ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
828 ShowMessageBox(IDS_CLEANACL_NOT_SUPPORTED, MB_ICONERROR, IDS_CLEANACL_NOT_SUPPORTED, names[i]);
832 changes = CleanAcl(ta);
836 /* now set the acl */
837 blob.in = AclToString(ta);
838 blob.in_size = strlen((char *)blob.in) + 1;
841 code = pioctl_T(names[i], VIOCSETAL, &blob, 1);
843 if (errno == EINVAL) {
844 ShowMessageBox(IDS_CLEANACL_INVALID_ARG, MB_ICONERROR, IDS_CLEANACL_INVALID_ARG, names[i]);
848 ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONERROR, 0, names[i], GetAfsError(errno));
855 // Derived from fs.c's ListAclCmd
856 BOOL GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& strNegative)
860 struct ViceIoctl blob;
862 int idf = 0; //getidf(as, parm_listacl_id);
866 blob.out_size = AFS_PIOCTL_MAXSIZE;
868 blob.in = blob.out = space;
870 code = pioctl_T(strDir, VIOCGETAL, &blob, 1);
872 ShowMessageBox(IDS_GETRIGHTS_ERROR, MB_ICONERROR, IDS_GETRIGHTS_ERROR, strDir, GetAfsError(errno));
876 ta = ParseAcl(space);
878 ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
882 ShowMessageBox(IDS_DFSACL_ERROR, MB_ICONERROR, IDS_DFSACL_ERROR);
887 // printf(" Default cell = %s\n", ta->cell);
892 for (te = ta->pluslist; te; te = te->next) {
893 strNormal.Add(te->name);
894 strNormal.Add(GetRightsString(te->rights, ta->dfs));
898 if (ta->nminus > 0) {
899 for (te = ta->minuslist; te; te = te->next) {
900 strNegative.Add(te->name);
901 strNegative.Add(GetRightsString(te->rights, ta->dfs));
908 struct AclEntry *FindList(struct AclEntry *pCurEntry, const char *entryName)
911 if (!foldcmp(pCurEntry->name, PCCHAR(entryName)))
913 pCurEntry = pCurEntry->next;
919 void ChangeList(struct Acl *pAcl, BYTE bNormalRights, const CString & entryName, LONG nEntryRights)
924 struct AclEntry *pEntry;
925 CStringUtf8 uEntryName(entryName);
929 pEntry = (bNormalRights ? pAcl->pluslist : pAcl->minuslist);
930 pEntry = FindList(pEntry, uEntryName);
932 /* Found the item already in the list. */
934 pEntry->rights = nEntryRights;
936 pAcl->nplus -= PruneList(&pAcl->pluslist, pAcl->dfs);
938 pAcl->nminus -= PruneList(&pAcl->minuslist, pAcl->dfs);
942 /* Otherwise we make a new item and plug in the new data. */
943 pEntry = (struct AclEntry *) malloc(sizeof (struct AclEntry));
946 strcpy(pEntry->name, uEntryName);
947 pEntry->rights = nEntryRights;
950 pEntry->next = pAcl->pluslist;
951 pAcl->pluslist = pEntry;
953 if (nEntryRights == 0 || nEntryRights == -1)
954 pAcl->nplus -= PruneList(&pAcl->pluslist, pAcl->dfs);
957 pEntry->next = pAcl->minuslist;
958 pAcl->minuslist = pEntry;
960 if (nEntryRights == 0)
961 pAcl->nminus -= PruneList(&pAcl->minuslist, pAcl->dfs);
965 enum rtype {add, destroy, deny};
967 static LONG Convert(const CString& strRights, int dfs, enum rtype *rtypep)
972 *rtypep = add; /* add rights, by default */
974 if (strRights == _T("read"))
975 return PRSFS_READ | PRSFS_LOOKUP;
976 if (strRights == _T("write"))
977 return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
978 if (strRights == _T("mail"))
979 return PRSFS_INSERT | PRSFS_LOCK | PRSFS_LOOKUP;
980 if (strRights == _T("all"))
981 return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
983 if (strRights == _T("none")) {
984 *rtypep = destroy; /* Remove entire entry */
988 len = strRights.GetLength();
991 for (i = 0; i < len; i++) {
992 TCHAR c = strRights[i];
993 if (c == _T('r')) mode |= PRSFS_READ;
994 else if (c == _T('l')) mode |= PRSFS_LOOKUP;
995 else if (c == _T('i')) mode |= PRSFS_INSERT;
996 else if (c == _T('d')) mode |= PRSFS_DELETE;
997 else if (c == _T('w')) mode |= PRSFS_WRITE;
998 else if (c == _T('k')) mode |= PRSFS_LOCK;
999 else if (c == _T('a')) mode |= PRSFS_ADMINISTER;
1001 fprintf(stderr, "illegal rights character '%c'.\n", c);
1008 BOOL SaveACL(const CString& strCellName, const CString& strDir, const CStringArray& normal, const CStringArray& negative)
1011 struct ViceIoctl blob;
1016 HOURGLASS hourglass;
1019 pAcl = EmptyAcl(strCellName);
1021 // Set its normal rights
1023 for (i = 0; i < normal.GetSize(); i += 2) {
1024 rights = Convert(normal[i + 1], 0, &rtype);
1025 ChangeList(pAcl, TRUE, normal[i], rights);
1028 // Set its negative rights
1029 for (i = 0; i < negative.GetSize(); i += 2) {
1030 rights = Convert(negative[i + 1], 0, &rtype);
1031 ChangeList(pAcl, FALSE, negative[i], rights);
1035 blob.in = AclToString(pAcl);
1037 blob.in_size = 1 + strlen((const char *)blob.in);
1039 code = pioctl_T(strDir, VIOCSETAL, &blob, 1);
1041 if (errno == EINVAL)
1042 ShowMessageBox(IDS_SAVE_ACL_EINVAL_ERROR, MB_ICONERROR, IDS_SAVE_ACL_EINVAL_ERROR, strDir);
1044 ShowMessageBox(IDS_SAVE_ACL_ERROR, MB_ICONERROR, IDS_SAVE_ACL_ERROR, strDir, GetAfsError(errno, strDir));
1052 BOOL CopyACL(const CString& strToDir, const CStringArray& normal, const CStringArray& negative, BOOL bClear)
1055 struct ViceIoctl blob;
1057 int idf = 0; // getidf(as, parm_copyacl_id);
1059 HOURGLASS hourglass;
1061 // Get ACL to copy to
1062 blob.out_size = AFS_PIOCTL_MAXSIZE;
1064 blob.in = blob.out = space;
1066 code = pioctl_T(strToDir, VIOCGETAL, &blob, 1);
1068 ShowMessageBox(IDS_ACL_READ_ERROR, MB_ICONERROR, IDS_ACL_READ_ERROR, strToDir, GetAfsError(errno, strToDir));
1073 pToAcl = EmptyAcl(space);
1075 pToAcl = ParseAcl(space);
1077 if (pToAcl == NULL) {
1078 ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
1085 ShowMessageBox(IDS_NO_DFS_COPY_ACL, MB_ICONERROR, IDS_NO_DFS_COPY_ACL, strToDir);
1092 // Set normal rights
1094 for (i = 0; i < normal.GetSize(); i += 2) {
1095 LONG rights = Convert(normal[i + 1], 0, &rtype);
1096 ChangeList(pToAcl, TRUE, normal[i], rights);
1099 // Set negative rights
1100 for (i = 0; i < negative.GetSize(); i += 2) {
1101 LONG rights = Convert(negative[i + 1], 0, &rtype);
1102 ChangeList(pToAcl, FALSE, normal[i], rights);
1105 // Save modified ACL
1106 blob.in = AclToString(pToAcl);
1108 blob.in_size = 1 + strlen((char *)blob.in);
1110 code = pioctl_T(strToDir, VIOCSETAL, &blob, 1);
1113 if (errno == EINVAL)
1114 ShowMessageBox(IDS_COPY_ACL_EINVAL_ERROR, MB_ICONERROR, IDS_COPY_ACL_EINVAL_ERROR, strToDir);
1116 ShowMessageBox(IDS_COPY_ACL_ERROR, MB_ICONERROR, IDS_COPY_ACL_ERROR, strToDir, GetAfsError(errno, strToDir));
1122 ShowMessageBox(IDS_COPY_ACL_OK, MB_OK|MB_ICONINFORMATION, IDS_COPY_ACL_OK);
1127 CString ParseMountPoint(const CString strFile, CString strMountPoint)
1132 CString strMountPointInfo;
1134 if (strMountPoint[0] == '#')
1135 strType = "Regular";
1136 else if (strMountPoint[0] == '%')
1137 strType = "Read/Write";
1139 int nColon = strMountPoint.Find(':');
1141 strCell = strMountPoint.Mid(1, nColon - 1);
1142 strVolume = strMountPoint.Mid(nColon + 1);
1144 strVolume = strMountPoint.Mid(1);
1146 strMountPointInfo = strFile + _T("\t") + strVolume + _T("\t") + strCell + _T("\t") + strType;
1148 return strMountPointInfo;
1151 CString ParseSymlink(const CString strFile, CString strSymlink)
1153 CString strSymlinkInfo;
1155 strSymlinkInfo = strFile + _T("\t") + strSymlink;
1157 return strSymlinkInfo;
1160 BOOL IsPathInAfs(const CString & strPath)
1162 struct ViceIoctl blob;
1163 cm_ioctlQueryOptions_t options;
1167 HOURGLASS hourglass;
1169 memset(&options, 0, sizeof(options));
1170 options.size = sizeof(options);
1171 options.field_flags |= CM_IOCTL_QOPTS_FIELD_LITERAL;
1172 options.literal = 1;
1173 blob.in_size = options.size; /* no variable length data */
1175 blob.out_size = sizeof(cm_fid_t);
1176 blob.out = (char *) &fid;
1178 code = pioctl_T(strPath, VIOCGETFID, &blob, 1);
1180 if ((errno == EINVAL) || (errno == ENOENT))
1187 IsFreelanceRoot(const CString& apath)
1189 struct ViceIoctl blob;
1193 blob.out_size = AFS_PIOCTL_MAXSIZE;
1196 code = pioctl_T(apath, VIOC_FILE_CELL_NAME, &blob, 1);
1198 return !strcmp("Freelance.Local.Root",space);
1199 return 1; /* assume it is because it is more restrictive that way */
1202 static const char * NetbiosName(void)
1204 static char buffer[1024] = "AFS";
1210 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
1211 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey);
1212 if (code == ERROR_SUCCESS) {
1213 dummyLen = sizeof(buffer);
1214 code = RegQueryValueExA(parmKey, "NetbiosName", NULL, NULL,
1215 (LPBYTE)buffer, &dummyLen);
1216 RegCloseKey (parmKey);
1218 strcpy(buffer, "AFS");
1223 static void FixNetbiosPath(CString& path)
1225 if (!IsPathInAfs(path)) {
1227 const char * nbname = NetbiosName();
1230 nbroot.Format(_T("\\\\%S\\"), nbname);
1232 nbroot.Format(_T("\\\\%s\\"), nbname);
1235 if (nbroot.CompareNoCase(path) == 0) {
1236 path.Append(_T("all\\"));
1241 #define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins"
1243 static BOOL IsAdmin (void)
1245 static BOOL fAdmin = FALSE;
1246 static BOOL fTested = FALSE;
1250 /* Obtain the SID for the AFS client admin group. If the group does
1251 * not exist, then assume we have AFS client admin privileges.
1253 PSID psidAdmin = NULL;
1254 DWORD dwSize, dwSize2;
1255 TCHAR pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ];
1256 TCHAR *pszRefDomain = NULL;
1257 SID_NAME_USE snu = SidTypeGroup;
1259 dwSize = sizeof(pszAdminGroup);
1261 if (!GetComputerName(pszAdminGroup, &dwSize)) {
1262 /* Can't get computer name. We return false in this case.
1263 Retain fAdmin and fTested. This shouldn't happen.*/
1270 lstrcat(pszAdminGroup, _T("\\"));
1271 lstrcat(pszAdminGroup, _T(AFSCLIENT_ADMIN_GROUPNAME));
1273 LookupAccountName(NULL, pszAdminGroup, NULL, &dwSize, NULL, &dwSize2, &snu);
1274 /* that should always fail. */
1276 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
1277 /* if we can't find the group, then we allow the operation */
1282 if (dwSize == 0 || dwSize2 == 0) {
1288 psidAdmin = (PSID)malloc(dwSize); memset(psidAdmin,0,dwSize);
1289 pszRefDomain = (TCHAR *)malloc(dwSize2);
1291 if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) {
1292 /* We can't lookup the group now even though we looked it up earlier.
1293 Could this happen? */
1296 /* Then open our current ProcessToken */
1299 if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken))
1302 if (!CheckTokenMembership(hToken, psidAdmin, &fAdmin)) {
1303 /* We'll have to allocate a chunk of memory to store the list of
1304 * groups to which this user belongs; find out how much memory
1308 PTOKEN_GROUPS pGroups;
1310 GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize);
1312 pGroups = (PTOKEN_GROUPS)malloc(dwSize);
1314 /* Allocate that buffer, and read in the list of groups. */
1315 if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize))
1317 /* Look through the list of group SIDs and see if any of them
1318 * matches the AFS Client Admin group SID.
1321 for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup)
1323 if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) {
1333 /* if do not have permission because we were not explicitly listed
1334 * in the Admin Client Group let's see if we are the SYSTEM account
1337 PTOKEN_USER pTokenUser;
1338 SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
1339 PSID pSidLocalSystem = 0;
1342 GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
1344 pTokenUser = (PTOKEN_USER)malloc(dwSize);
1346 if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize))
1347 gle = GetLastError();
1349 if (AllocateAndInitializeSid( &SIDAuth, 1,
1350 SECURITY_LOCAL_SYSTEM_RID,
1351 0, 0, 0, 0, 0, 0, 0,
1354 if (EqualSid(pTokenUser->User.Sid, pSidLocalSystem)) {
1358 FreeSid(pSidLocalSystem);
1376 CString Parent(const CString& path)
1378 int last_slash = path.ReverseFind(_T('\\'));
1380 if (last_slash != -1) {
1381 CString ret = path.Left(last_slash + 1);
1384 if (path.GetLength() >= 2 && path[1] == _T(':')) {
1385 CString ret = path.Left(2);
1386 ret.AppendChar(_T('.'));
1389 CString ret = _T(".");
1395 CString LastComponent(const CString& path)
1397 int last_slash = path.ReverseFind(_T('\\'));
1399 if (last_slash != -1) {
1400 CString ret = path.Mid(last_slash + 1);
1403 if (path.GetLength() >= 2 && path[1] == _T(':')) {
1404 CString ret = path.Mid(2);
1414 GetCell(const CString & path)
1416 char cellname[MAXCELLCHARS];
1418 struct ViceIoctl blob;
1421 blob.out_size = sizeof(cellname);
1422 blob.out = cellname;
1424 code = pioctl_T(path, VIOC_FILE_CELL_NAME, &blob, 1);
1431 return Utf8ToCString(cellname);
1436 BOOL ListMount(CStringArray& files)
1439 struct ViceIoctl blob;
1442 CString parent_dir; /* Parent directory of true name */
1443 CStringUtf8 last_component; /* Last component of true name */
1445 CStringArray mountPoints;
1447 HOURGLASS hourglass;
1451 for (int i = 0; i < files.GetSize(); i++) {
1452 int last_slash = files[i].ReverseFind(_T('\\'));
1454 if (last_slash != -1) {
1455 last_component.SetString( files[i].Mid(last_slash + 1) );
1456 parent_dir.SetString( files[i].Left(last_slash + 1) );
1457 FixNetbiosPath(parent_dir);
1459 // The path is of the form "C:foo" or just "foo". If
1460 // there is a drive, then use the current directory of
1461 // that drive. Otherwise we just use '.'.
1463 if (files[i].GetLength() >= 2 && files[i][1] == _T(':')) {
1464 parent_dir.Format(_T("%c:."), files[i][0]);
1465 last_component.SetString( files[i].Mid(2) );
1467 parent_dir.SetString( _T("."));
1468 last_component.SetString( files[i] );
1472 blob.in_size = last_component.GetLength() + 1;
1473 blob.in = last_component.GetBuffer();
1474 blob.out_size = AFS_PIOCTL_MAXSIZE;
1476 memset(space, 0, AFS_PIOCTL_MAXSIZE);
1478 code = pioctl_T(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
1480 last_component.ReleaseBuffer();
1484 space[AFS_PIOCTL_MAXSIZE - 1] = '\0';
1485 nPos = strlen(space) - 1;
1486 if (space[nPos] == '.')
1488 mountPoints.Add(ParseMountPoint(StripPath(files[i]), Utf8ToCString(space)));
1491 if (errno == EINVAL)
1492 mountPoints.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(files[i])));
1494 mountPoints.Add(GetMessageString(IDS_LIST_MOUNT_POINT_ERROR, GetAfsError(errno, StripPath(files[i]))));
1498 CMountPointsDlg dlg;
1499 dlg.SetMountPoints(mountPoints);
1506 MakeMount(const CString& strDir,
1507 const CString& strVolName,
1508 const CString& strInCellName,
1512 struct ViceIoctl blob;
1513 HOURGLASS hourglass;
1515 ASSERT(strVolName.GetLength() < 64);
1517 CString strParent = Parent(strDir);
1519 FixNetbiosPath(strParent);
1520 if (!IsPathInAfs(strParent)) {
1521 ShowMessageBox(IDS_MAKE_MP_NOT_AFS_ERROR, MB_ICONERROR, IDS_MAKE_MP_NOT_AFS_ERROR);
1525 CString strPath = strParent + LastComponent(strDir);
1527 if ( IsFreelanceRoot(strParent) && !IsAdmin() ) {
1528 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR,
1529 IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
1535 strMount.Format(_T("%c%s%s%s."),
1536 ((bRW)?_T('%'):_T('#')),
1538 ((strInCellName.IsEmpty())?_T(""):_T(":")),
1541 CStringUtf8 ustrMount(strMount);
1544 blob.in_size = ustrMount.GetLength() + 1;
1545 blob.in = ustrMount.GetBuffer();
1548 code = pioctl_T(strPath, VIOC_AFS_CREATE_MT_PT, &blob, 0);
1550 ustrMount.ReleaseBuffer();
1553 ShowMessageBox(IDS_MOUNT_POINT_ERROR, MB_ICONERROR, IDS_MOUNT_POINT_ERROR, GetAfsError(errno, strDir));
1562 long fs_ExtractDriveLetter(const char *inPathp, char *outPathp)
1564 if (inPathp[0] != 0 && inPathp[1] == ':') {
1565 /* there is a drive letter */
1566 *outPathp++ = *inPathp++;
1567 *outPathp++ = *inPathp++;
1575 /* strip the drive letter from a component */
1576 long fs_StripDriveLetter(const char *inPathp, char *outPathp, long outSize)
1578 char tempBuffer[1000];
1579 strcpy(tempBuffer, inPathp);
1580 if (tempBuffer[0] != 0 && tempBuffer[1] == ':') {
1581 /* drive letter present */
1582 strcpy(outPathp, tempBuffer+2);
1585 /* no drive letter present */
1586 strcpy(outPathp, tempBuffer);
1592 BOOL RemoveSymlink(const CString& strName)
1596 struct ViceIoctl blob;
1597 char lsbuffer[1024];
1599 HOURGLASS hourglass;
1601 CString strParent = Parent(strName);
1602 CStringUtf8 ustrLast(LastComponent(strName));
1603 FixNetbiosPath(strParent);
1605 if ( IsFreelanceRoot(strParent) && !IsAdmin() ) {
1606 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
1610 blob.in_size = ustrLast.GetLength() + 1;
1611 blob.in = ustrLast.GetBuffer();
1612 blob.out = lsbuffer;
1613 blob.out_size = sizeof(lsbuffer);
1614 code = pioctl_T(strParent, VIOC_LISTSYMLINK, &blob, 0);
1615 ustrLast.ReleaseBuffer();
1619 blob.in_size = ustrLast.GetLength() + 1;
1620 blob.in = ustrLast.GetBuffer();
1622 code = pioctl_T(strParent, VIOC_DELSYMLINK, &blob, 0);
1624 ustrLast.ReleaseBuffer();
1629 BOOL IsSymlink(const CString& strName)
1631 struct ViceIoctl blob;
1634 HOURGLASS hourglass;
1636 CStringUtf8 ustrLast(LastComponent(strName));
1637 CString strParent = Parent(strName);
1639 FixNetbiosPath(strParent);
1641 blob.in_size = ustrLast.GetLength() + 1;
1642 blob.in = ustrLast.GetBuffer();
1643 blob.out_size = AFS_PIOCTL_MAXSIZE;
1645 memset(space, 0, AFS_PIOCTL_MAXSIZE);
1647 code = pioctl_T(strParent, VIOC_LISTSYMLINK, &blob, 1);
1649 ustrLast.ReleaseBuffer();
1655 BOOL IsMountPoint(const CString& path)
1658 struct ViceIoctl blob;
1659 char lsbuffer[1024];
1661 HOURGLASS hourglass;
1663 CString parent = Parent(path);
1664 FixNetbiosPath(parent);
1666 CStringUtf8 mountpoint(LastComponent(path));
1668 blob.in_size = mountpoint.GetLength() + 1;
1669 blob.in = mountpoint.GetBuffer();
1670 blob.out = lsbuffer;
1671 blob.out_size = sizeof(lsbuffer);
1673 code = pioctl_T(parent, VIOC_AFS_STAT_MT_PT, &blob, 0);
1675 mountpoint.ReleaseBuffer();
1682 * Delete AFS mount points. Variables are used as follows:
1683 * tbuffer: Set to point to the null-terminated directory name of the mount point
1684 * (or ``.'' if none is provided)
1685 * tp: Set to point to the actual name of the mount point to nuke.
1687 BOOL RemoveMount(CStringArray& files)
1690 struct ViceIoctl blob;
1692 CStringArray results;
1696 HOURGLASS hourglass;
1698 for (int i = 0; i < files.GetSize(); i++) {
1699 if (!IsMountPoint(files[i])) {
1701 if (errno == EINVAL)
1702 results.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(files[i])));
1704 results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
1705 continue; // don't bother trying
1708 CString parent = Parent(files[i]);
1709 CStringUtf8 mountpoint(LastComponent(files[i]));
1710 FixNetbiosPath(parent);
1712 if ( IsFreelanceRoot(parent) && !IsAdmin() ) {
1713 results.Add(GetMessageString(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, StripPath(files[i])));
1715 continue; /* skip */
1719 blob.in_size = mountpoint.GetLength() + 1;
1720 blob.in = mountpoint.GetBuffer();
1722 code = pioctl_T(parent, VIOC_AFS_DELETE_MT_PT, &blob, 0);
1724 mountpoint.ReleaseBuffer();
1728 results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
1730 results.Add(GetMessageString(IDS_DELETED));
1733 LoadString (str, IDS_REMOVE_MP);
1734 LoadString (str2, IDS_REMOVE_MP_COLUMN);
1735 CResultsDlg dlg(REMOVE_MOUNT_POINTS_HELP_ID);
1736 dlg.SetContents(str, str2, StripPath(files), results);
1742 BOOL GetVolumeInfo(CString strFile, CVolInfo& volInfo)
1745 struct ViceIoctl blob;
1746 struct VolumeStatus *status;
1749 HOURGLASS hourglass;
1751 volInfo.m_strFilePath = strFile;
1752 volInfo.m_strFileName = StripPath(strFile);
1755 volInfo.m_strName = "VolumeName";
1757 volInfo.m_nQuota = 20 * 1024 * 1024;
1758 volInfo.m_nNewQuota = volInfo.m_nQuota;
1759 volInfo.m_nUsed = volInfo.m_nQuota / 2;
1760 volInfo.m_nPartSize = 50 * 1024 * 1024;
1761 volInfo.m_nPartFree = 30 * 1024 * 1024;
1762 volInfo.m_nDup = -1;
1766 blob.out_size = AFS_PIOCTL_MAXSIZE;
1770 code = pioctl_T(strFile, VIOCGETVOLSTAT, &blob, 1);
1771 if (code || blob.out_size < sizeof(*status)) {
1772 volInfo.m_strErrorMsg = GetAfsError(errno, strFile);
1776 status = (VolumeStatus *)space;
1777 name = (char *)status + sizeof(*status);
1779 volInfo.m_strName = Utf8ToCString(name);
1780 volInfo.m_nID = status->Vid;
1781 volInfo.m_nQuota = status->MaxQuota;
1782 volInfo.m_nNewQuota = status->MaxQuota;
1783 volInfo.m_nUsed = status->BlocksInUse;
1784 volInfo.m_nPartSize = status->PartMaxBlocks;
1785 volInfo.m_nPartFree = status->PartBlocksAvail;
1786 volInfo.m_nDup = -1;
1791 BOOL SetVolInfo(CVolInfo& volInfo)
1794 struct ViceIoctl blob;
1795 struct VolumeStatus *status;
1798 HOURGLASS hourglass;
1800 blob.out_size = AFS_PIOCTL_MAXSIZE;
1801 blob.in_size = sizeof(*status) + 3; /* for the three terminating nulls */
1805 status = (VolumeStatus *)space;
1806 status->MinQuota = -1;
1807 status->MaxQuota = volInfo.m_nNewQuota;
1809 input = (char *)status + sizeof(*status);
1810 *(input++) = '\0'; /* never set name: this call doesn't change vldb */
1811 *(input++) = '\0'; // No offmsg
1812 *(input++) = '\0'; // No motd
1815 FILE *fp = OpenFile(szLogFileName, "a");
1817 fprintf(fp, "\nSetVolInfo() pioctl parms:\n");
1818 fprintf(fp, "\tpathp = %s\n\topcode = VIOCSETVOLSTAT (%d)\n\tblobp = %ld\n", PCCHAR(volInfo.m_strFilePath), VIOCSETVOLSTAT, &blob);
1819 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);
1820 fprintf(fp, "\t\t\tstatus->MinQuota = %ld\n", status->MinQuota);
1821 fprintf(fp, "\t\t\tstatus->MaxQuota = %ld\n", status->MaxQuota);
1822 fprintf(fp, "\t\t\tOther status fields aren't set\n");
1823 fprintf(fp, "\t\t\t3 nulls follow the VolumeStatus structure.\n");
1824 fprintf(fp, "\tfollow = 1\n");
1829 code = pioctl_T(volInfo.m_strFilePath, VIOCSETVOLSTAT, &blob, 1);
1830 if (code || blob.out_size < sizeof(*status)) {
1831 ShowMessageBox(IDS_SET_QUOTA_ERROR, MB_ICONERROR, IDS_SET_QUOTA_ERROR, GetAfsError(errno, volInfo.m_strName));
1838 void GetCellName(const CString& cellNamep, struct afsconf_cell *infop)
1840 CStringUtf8 uCellName(cellNamep);
1842 StringCbCopyA(infop->name, sizeof(infop->name), uCellName);
1845 BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast)
1848 struct ViceIoctl blob;
1851 struct afsconf_cell info;
1852 struct chservinfo checkserv;
1854 HOURGLASS hourglass;
1856 memset(&checkserv, 0, sizeof(struct chservinfo));
1857 blob.in_size = sizeof(struct chservinfo);
1858 blob.in = (caddr_t)&checkserv;
1860 blob.out_size = AFS_PIOCTL_MAXSIZE;
1862 memset(space, 0, sizeof(afs_int32)); /* so we assure zero when nothing is copied back */
1864 if (nCellsToCheck == SPECIFIC_CELL) {
1866 GetCellName(strCellName, &info);
1867 strcpy(checkserv.tbuffer,info.name);
1868 checkserv.tsize = strlen(info.name) + 1;
1870 if (nCellsToCheck != ALL_CELLS)
1872 strcpy(checkserv.tbuffer, "\0");
1873 checkserv.tsize = 0;
1876 temp |= 1; /* set fast flag */
1878 checkserv.magic = 0x12345678; /* XXX */
1879 checkserv.tflags = temp;
1880 checkserv.tinterval = -1; /* don't change current interval */
1882 code = pioctl_utf8(0, VIOCCKSERV, &blob, 1);
1884 ShowMessageBox(IDS_CHECK_SERVERS_ERROR, MB_ICONERROR, IDS_CHECK_SERVERS_ERROR, GetAfsError(errno, CString()));
1888 memcpy(&temp, space, sizeof(LONG));
1891 ShowMessageBox(IDS_ALL_SERVERS_RUNNING, MB_OK|MB_ICONINFORMATION, IDS_ALL_SERVERS_RUNNING);
1895 CStringArray servers;
1896 for (j = 0; j < AFS_MAXHOSTS; j++) {
1897 memcpy(&temp, space + j * sizeof(LONG), sizeof(LONG));
1901 char *name = hostutil_GetNameByINet(temp);
1905 CDownServersDlg dlg;
1906 dlg.SetServerNames(servers);
1912 BOOL GetTokenInfo(CStringArray& tokenInfo)
1916 time_t current_time;
1917 time_t tokenExpireTime;
1921 struct ktc_principal serviceName, clientName;
1922 struct ktc_token token;
1924 CString strTokenInfo;
1925 CString strUserName;
1926 CString strCellName;
1929 // tokenInfo.Add("");
1933 HOURGLASS hourglass;
1935 // printf("\nTokens held by the Cache Manager:\n\n");
1937 current_time = time(0);
1940 rc = ktc_ListTokens(cellNum, &cellNum, &serviceName);
1941 if (rc == KTC_NOENT) {
1943 // printf(" --End of list --\n");
1946 else if (rc == KTC_NOCM) {
1947 ShowMessageBox(IDS_GET_TOKENS_NO_AFS_SERVICE);
1948 // printf("AFS service may not have started\n");
1952 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR, MB_ICONERROR, IDS_GET_TOKENS_UNEXPECTED_ERROR, rc);
1954 // printf("Unexpected error, code %d\n", rc);
1958 rc = ktc_GetToken(&serviceName, &token, sizeof(token), &clientName);
1960 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR2, MB_ICONERROR, IDS_GET_TOKENS_UNEXPECTED_ERROR2,
1961 serviceName.name, serviceName.instance, serviceName.cell, rc);
1965 tokenExpireTime = token.endTime;
1967 strcpy(userName, clientName.name);
1968 if (clientName.instance[0] != 0) {
1969 strcat(userName, ".");
1970 strcat(userName, clientName.instance);
1973 BOOL bShowName = FALSE;
1975 if (userName[0] == '\0')
1976 ; //printf("Tokens");
1977 // AFS ID is not returned at this time.
1978 // else if (strncmp(userName, "AFS ID", 6) == 0)
1979 // printf("User's (%s) tokens", userName);
1980 // sscanf(userName, "(AFS ID %s)", szAfsID);
1981 else if (strncmp(userName, "Unix UID", 8) == 0)
1982 ; //printf("Tokens");
1984 strUserName = userName;
1985 // printf("User %s's tokens", userName);
1987 // printf(" for %s%s%s@%s ", serviceName.name, serviceName.instance[0] ? "." : "", serviceName.instance, serviceName.cell);
1988 strCellName = serviceName.cell;
1990 if (tokenExpireTime <= current_time)
1991 strExpir = "[>> Expired <<]";
1992 // printf("[>> Expired <<]\n");
1994 expireString = ctime(&tokenExpireTime);
1995 expireString += 4; /* Skip day of week */
1996 expireString[12] = '\0'; /* Omit secs & year */
1997 // printf("[Expires %s]\n", expireString);
1999 strExpir.Format(_T("%S"), expireString);
2001 strExpir.Format(_T("%s"), expireString);
2005 strTokenInfo = strUserName + "\t" + strCellName + "\t" + strExpir + "\t" + strCellName;
2006 tokenInfo.Add(strTokenInfo);
2010 // printf("Press <Enter> or <Return> when finished: ");
2015 UINT MakeSymbolicLink(const CString& strName, const CString& strTarget)
2017 struct ViceIoctl blob;
2019 HOURGLASS hourglass;
2021 CString strParent = Parent(strName);
2022 FixNetbiosPath(strParent);
2024 if ( IsFreelanceRoot(strParent) && !IsAdmin() ) {
2025 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
2029 CStringUtf8 ustrTarget(strTarget);
2031 blob.in_size = ustrTarget.GetLength() + 1;
2032 blob.in = ustrTarget.GetBuffer();
2036 code = pioctl_T(strName, VIOC_SYMLINK, &blob, 0);
2038 ustrTarget.ReleaseBuffer();
2045 void ListSymbolicLinkPath(const char *strName,char *strPath,UINT nlenPath)
2047 ASSERT(nlenPath<MAX_PATH);
2048 struct ViceIoctl blob;
2049 char orig_name[MAX_PATH+1]; /*Original name, may be modified*/
2050 char true_name[MAX_PATH+1]; /*``True'' dirname (e.g., symlink target)*/
2051 char parent_dir[MAX_PATH+1]; /*Parent directory of true name*/
2052 char *last_component; /*Last component of true name*/
2055 HOURGLASS hourglass;
2057 strcpy(orig_name, strName);
2058 strcpy(true_name, orig_name);
2060 * Find rightmost slash, if any.
2062 last_component = (char *) strrchr(true_name, '\\');
2063 if (!last_component)
2064 last_component = (char *) strrchr(true_name, '/');
2065 if (last_component) {
2067 * Found it. Designate everything before it as the parent directory,
2068 * everything after it as the final component.
2070 strncpy(parent_dir, true_name, last_component - true_name + 1);
2071 parent_dir[last_component - true_name + 1] = 0;
2072 last_component++; /*Skip the slash*/
2074 if (!IsPathInAfs(parent_dir)) {
2075 const char * nbname = NetbiosName();
2076 int len = strlen(nbname);
2078 if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
2079 parent_dir[len+2] == '\\' &&
2080 parent_dir[len+3] == '\0' &&
2081 !strnicmp(nbname,&parent_dir[2],len))
2083 sprintf(parent_dir,"\\\\%s\\all\\", nbname);
2089 * No slash appears in the given file name. Set parent_dir to the current
2090 * directory, and the last component as the given name.
2092 fs_ExtractDriveLetter(true_name, parent_dir);
2093 strcat(parent_dir, ".");
2094 last_component = true_name;
2095 fs_StripDriveLetter(true_name, true_name, sizeof(true_name));
2097 blob.in = last_component;
2098 blob.in_size = strlen(last_component)+1;
2099 blob.out_size = AFS_PIOCTL_MAXSIZE;
2101 memset(space, 0, AFS_PIOCTL_MAXSIZE);
2102 if ((code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1)))
2103 strcpy(space,"???");
2104 ASSERT(strlen(space)<MAX_PATH);
2105 strncpy(strPath,space,nlenPath);
2108 BOOL ListSymlink(CStringArray& files)
2111 struct ViceIoctl blob;
2113 CStringArray symlinks;
2115 HOURGLASS hourglass;
2119 for (int i = 0; i < files.GetSize(); i++) {
2121 CString strParent = Parent(files[i]);
2122 CStringUtf8 ustrLast(LastComponent(files[i]));
2124 FixNetbiosPath(strParent);
2126 blob.in_size = ustrLast.GetLength() + 1;
2127 blob.in = ustrLast.GetBuffer();
2128 blob.out_size = AFS_PIOCTL_MAXSIZE;
2130 memset(space, 0, AFS_PIOCTL_MAXSIZE);
2132 code = pioctl_T(strParent, VIOC_LISTSYMLINK, &blob, 1);
2134 ustrLast.ReleaseBuffer();
2140 space[AFS_PIOCTL_MAXSIZE - 1] = '\0';
2141 syml = Utf8ToCString(space);
2142 len = syml.GetLength();
2145 if (syml[len - 1] == _T('.'))
2146 syml.Truncate(len - 1);
2149 symlinks.Add(ParseSymlink(StripPath(files[i]), syml));
2153 if (errno == EINVAL)
2154 symlinks.Add(GetMessageString(IDS_NOT_SYMLINK_ERROR, StripPath(files[i])));
2156 symlinks.Add(GetMessageString(IDS_LIST_MOUNT_POINT_ERROR, GetAfsError(errno, StripPath(files[i]))));
2161 dlg.SetSymlinks(symlinks);