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 "symlinks_dlg.h"
25 #include "hourglass.h"
26 #include "down_servers_dlg.h"
29 #include <rx/rx_globals.h>
33 #include <afs/cellconfig.h>
34 #include <afs/vldbint.h>
35 #include <afs/volser.h>
37 #include <WINNT\afsreg.h>
41 #define STRSAFE_NO_DEPRECATE
44 #define PCCHAR(str) ((char *)(const char *)(str))
45 #define VL_NOENT (363524L)
51 #define MAXINSIZE 1300 /* pioctl complains if data is larger than this */
52 #define VMSGSIZE 128 /* size of msg buf in volume hdr */
54 #define MAXCELLCHARS 64
55 #define MAXHOSTCHARS 64
56 #define MAXHOSTSPERCELL 8
58 static char space[MAXSIZE];
59 static char tspace[1024];
61 static struct ubik_client *uclient;
62 static int rxInitDone = 0;
63 static char pn[] = "fs";
65 // #define LOGGING_ON // Enable this to log certain pioctl calls
68 static char *szLogFileName = "afsguilog.txt";
72 class CStringUtf8 : public CStringA
75 CStringUtf8(const CStringW& csw) : CStringA()
80 CStringUtf8(const char * cp) : CStringA(cp) {}
82 CStringUtf8() :CStringA() {}
84 void SetString(const CStringW& csw)
89 rv = WideCharToMultiByte(CP_UTF8, 0, csw, -1,
90 buffer, sizeof(buffer),
94 CStringA::SetString(buffer);
96 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
99 cb_req = WideCharToMultiByte(CP_UTF8, 0, csw, -1, NULL, 0, NULL, FALSE);
103 WideCharToMultiByte(CP_UTF8, 0, csw, -1, CStringA::GetBuffer(cb_req), cb_req, NULL, FALSE);
104 CStringA::ReleaseBuffer();
114 static CString _Utf8ToCString(const char * ustr)
119 cch = MultiByteToWideChar(CP_UTF8, 0, ustr, -1, NULL, 0);
126 cch = MultiByteToWideChar(CP_UTF8, 0, ustr, -1, cs.GetBuffer(cch), cch);
133 long pioctl_T(const CString& path, long opcode, struct ViceIoctl * blob, int follow)
135 CStringUtf8 upath(path);
137 return pioctl_utf8(PCCHAR(upath), opcode, blob, follow);
140 #define Utf8ToCString(cs) CStringUtf8::_Utf8ToCString(cs)
142 #define pioctl_T(path, op, vblob, follow) pioctl(PCCHAR(path), op, vblob, follow)
143 #define Utf8ToCString(cs) (cs)
149 VLDBInit(int noAuthFlag, struct afsconf_cell *info)
153 code = ugen_ClientInit(noAuthFlag, (char *)AFSDIR_CLIENT_ETC_DIRPATH,
154 info->name, 0, &uclient,
155 NULL, pn, rxkad_clear,
156 VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 50,
157 0, 0, USER_SERVICE_ID);
163 OpenFile(char *file, char *rwp)
170 code = GetWindowsDirectoryA(wdir, sizeof(wdir));
171 if (code == 0 || code > sizeof(wdir))
174 /* add trailing backslash, if required */
176 if (wdir[tlen - 1] != '\\')
181 fp = fopen(wdir, rwp);
186 CString StripPath(CString& strPath)
188 int nIndex = strPath.ReverseFind('\\');
190 CString strFile = strPath.Mid(nIndex + 1);
191 if (strFile.IsEmpty())
197 CStringArray& StripPath(CStringArray& files)
199 for (int i = 0; i < files.GetSize(); i++)
200 files[i] = StripPath(files[i]);
205 void Flush(const CStringArray& files)
208 struct ViceIoctl blob;
213 for (int i = 0; i < files.GetSize(); i++) {
214 blob.in_size = blob.out_size = 0;
216 code = pioctl_T(files[i], VIOCFLUSH, &blob, 0);
220 ShowMessageBox(IDS_FLUSH_FAILED, MB_ICONERROR, IDS_FLUSH_FAILED, files[i]);
222 ShowMessageBox(IDS_FLUSH_ERROR, MB_ICONERROR, IDS_FLUSH_ERROR, files[i], strerror(errno));
227 ShowMessageBox(IDS_FLUSH_OK, MB_ICONINFORMATION, IDS_FLUSH_OK);
230 void FlushVolume(const CStringArray& files)
233 struct ViceIoctl blob;
238 for (int i = 0; i < files.GetSize(); i++) {
239 blob.in_size = blob.out_size = 0;
241 code = pioctl_T(files[i], VIOC_FLUSHVOLUME, &blob, 0);
244 ShowMessageBox(IDS_FLUSH_VOLUME_ERROR, MB_ICONERROR, IDS_FLUSH_VOLUME_ERROR, files[i], strerror(errno));
249 ShowMessageBox(IDS_FLUSH_VOLUME_OK, MB_ICONINFORMATION, IDS_FLUSH_VOLUME_OK);
252 void WhichCell(CStringArray& files)
255 struct ViceIoctl blob;
260 CStringArray results;
266 for (int i = 0; i < files.GetSize(); i++) {
268 blob.out_size = MAXSIZE;
271 code = pioctl_T(files[i], VIOC_FILE_CELL_NAME, &blob, 1);
273 if (code == ENOENT) {
274 LoadString (str, IDS_CANT_GET_CELL);
277 results.Add(GetAfsError(errno));
279 results.Add(Utf8ToCString(space));
283 LoadString (str, IDS_SHOW_CELL);
284 LoadString (str2, IDS_SHOW_CELL_COLUMN);
285 CResultsDlg dlg(SHOW_CELL_HELP_ID);
286 dlg.SetContents(str, str2, StripPath(files), results);
293 struct ViceIoctl blob;
298 blob.in = (char *) 0;
299 blob.out_size = MAXSIZE;
302 code = pioctl((char *) 0, VIOC_GET_WS_CELL, &blob, 1);
305 //Die(errno, (char *) 0);
308 //printf("This workstation belongs to cell '%s'\n", space);
314 struct ViceIoctl blob;
318 code = pioctl(0, VIOCCKBACK, &blob, 1);
320 ShowMessageBox(IDS_CHECK_VOLUMES_ERROR, MB_ICONERROR, IDS_CHECK_VOLUMES_ERROR, GetAfsError(errno, CString()));
324 ShowMessageBox(IDS_CHECK_VOLUMES_OK, MB_OK|MB_ICONINFORMATION, IDS_CHECK_VOLUMES_OK);
329 void SetCacheSizeCmd(LONG nNewCacheSize)
332 struct ViceIoctl blob;
336 blob.in = (char *) &nNewCacheSize;
337 blob.in_size = sizeof(LONG);
340 code = pioctl(0, VIOCSETCACHESIZE, &blob, 1);
342 // Die(errno, (char *) 0);
344 // printf("New cache size set.\n");
347 void WhereIs(CStringArray& files)
350 struct ViceIoctl blob;
351 CStringArray servers;
352 CStringArray resultFiles;
358 for (int i = 0; i < files.GetSize(); i++) {
359 blob.out_size = MAXSIZE;
362 memset(space, 0, sizeof(space));
364 code = pioctl_T(files[i], VIOCWHEREIS, &blob, 1);
366 resultFiles.Add(StripPath(files[i]));
367 servers.Add(GetAfsError(errno));
371 LONG *hosts = (LONG *)space;
375 for (int j = 0; j < MAXHOSTS; j++) {
378 char *hostName = hostutil_GetNameByINet(hosts[j]);
380 resultFiles.Add(StripPath(files[i]));
383 resultFiles.Add(" ");
384 servers.Add(hostName);
388 LoadString (str, IDS_SHOW_FS);
389 LoadString (str2, IDS_SHOW_FS_COLUMN);
390 CResultsDlg dlg(SHOW_FILE_SERVERS_HELP_ID);
391 dlg.SetContents(str, str2, resultFiles, servers);
396 CMtoUNIXerror(int cm_code)
399 case CM_ERROR_TIMEDOUT:
401 case CM_ERROR_NOACCESS:
403 case CM_ERROR_NOSUCHFILE:
409 case CM_ERROR_EXISTS:
411 case CM_ERROR_CROSSDEVLINK:
413 case CM_ERROR_NOTDIR:
417 case CM_ERROR_READONLY:
419 case CM_ERROR_WOULDBLOCK:
421 case CM_ERROR_NOSUCHCELL:
422 return ESRCH; /* hack */
423 case CM_ERROR_NOSUCHVOLUME:
424 return EPIPE; /* hack */
425 case CM_ERROR_NOMORETOKENS:
426 return EDOM; /* hack */
427 case CM_ERROR_TOOMANYBUFS:
428 return EFBIG; /* hack */
430 if (cm_code > 0 && cm_code < EILSEQ)
437 CString GetAfsError(int code, const TCHAR *filename)
441 code = CMtoUNIXerror(code);
443 if (code == EINVAL) {
445 strMsg.Format(_T("Invalid argument; it is possible that the file is not in AFS"));
447 strMsg.Format(_T("Invalid argument"));
448 } else if (code == ENOENT) {
450 strMsg.Format(_T("The file does not exist"));
452 strMsg.Format(_T("No such file returned"));
453 } else if (code == EROFS) {
454 strMsg.Format(_T("You can not change a backup or readonly volume"));
455 } else if (code == EACCES || code == EPERM) {
456 strMsg.Format(_T("You do not have the required rights to do this operation"));
457 } else if (code == ENODEV) {
458 strMsg.Format(_T("AFS service may not have started"));
459 } else if (code == ESRCH) {
460 strMsg.Format(_T("Cell name not recognized"));
461 } else if (code == ETIMEDOUT) {
462 strMsg.Format(_T("Connection timed out"));
463 } else if (code == EPIPE) {
464 strMsg.Format(_T("Volume name or ID not recognized"));
466 strMsg.Format(_T("Error 0x%x occurred"), code);
473 /************************************************************************
474 ************************** ACL Code *************************************
475 ************************************************************************/
477 typedef char sec_rgy_name_t[1025]; /* A DCE definition */
480 struct AclEntry *next;
486 int dfs; // Originally true if a dfs acl; now also the type
487 // of the acl (1, 2, or 3, corresponding to object,
488 // initial dir, or initial object).
489 sec_rgy_name_t cell; // DFS cell name
492 struct AclEntry *pluslist;
493 struct AclEntry *minuslist;
496 int foldcmp (register char *a, register char *b)
502 if (t >= 'A' && t <= 'Z') t += 0x20;
503 if (u >= 'A' && u <= 'Z') u += 0x20;
504 if (t != u) return 1;
505 if (t == 0) return 0;
509 extern "C" void ZapList(struct AclEntry *alist)
511 register struct AclEntry *tp, *np;
513 for (tp = alist; tp; tp = np) {
519 extern "C" void ZapAcl (struct Acl *acl)
521 ZapList(acl->pluslist);
522 ZapList(acl->minuslist);
526 extern "C" int PruneList (struct AclEntry **ae, int dfs)
528 struct AclEntry **lp = ae;
529 struct AclEntry *te, *ne;
532 for (te = *ae; te; te = ne) {
533 if ((!dfs && te->rights == 0) || te->rights == -1) {
548 char *SkipLine (register char *astr)
550 while (*astr != '\n')
558 /* tell if a name is 23 or -45 (digits or minus digits), which are bad names we must prune */
559 static int BadName(register char *aname)
563 /* all must be '-' or digit to be bad */
564 while (tc = *aname++) {
565 if ((tc != '-') && (tc < '0' || tc > '9'))
572 CString GetRightsString(register LONG arights, int dfs)
577 if (arights & PRSFS_READ) str += _T("r");
578 if (arights & PRSFS_LOOKUP) str += _T("l");
579 if (arights & PRSFS_INSERT) str += _T("i");
580 if (arights & PRSFS_DELETE) str += _T("d");
581 if (arights & PRSFS_WRITE) str += _T("w");
582 if (arights & PRSFS_LOCK) str += _T("k");
583 if (arights & PRSFS_ADMINISTER) str += _T("a");
587 if (arights & DFS_READ) str += _T("r"); else str += _T("-");
588 if (arights & DFS_WRITE) str += _T("w"); else printf(_T("-"));
589 if (arights & DFS_EXECUTE) str += _T("x"); else printf(_T("-"));
590 if (arights & DFS_CONTROL) str += _T("c"); else printf(_T("-"));
591 if (arights & DFS_INSERT) str += _T("i"); else printf(_T("-"));
592 if (arights & DFS_DELETE) str += _T("d"); else printf(_T("-"));
593 if (arights & (DFS_USRALL)) str += _T("+");
600 char *AclToString(struct Acl *acl)
602 static char mydata[MAXSIZE];
603 char tstring[MAXSIZE];
608 sprintf(dfsstring, " dfs:%d %s", acl->dfs, acl->cell);
611 sprintf(mydata, "%d%s\n%d\n", acl->nplus, dfsstring, acl->nminus);
613 for(tp = acl->pluslist; tp; tp = tp->next) {
614 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
615 strcat(mydata, tstring);
618 for(tp = acl->minuslist; tp; tp = tp->next) {
619 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
620 strcat(mydata, tstring);
626 struct Acl *EmptyAcl(const CString& strCellName)
628 register struct Acl *tp;
629 CStringUtf8 ustrCell(strCellName);
631 tp = (struct Acl *)malloc(sizeof (struct Acl));
632 tp->nplus = tp->nminus = 0;
633 tp->pluslist = tp->minuslist = 0;
635 StringCbCopyA(tp->cell, sizeof(tp->cell), ustrCell);
640 struct Acl *EmptyAcl(char *astr)
642 register struct Acl *tp;
645 tp = (struct Acl *)malloc(sizeof (struct Acl));
646 tp->nplus = tp->nminus = 0;
647 tp->pluslist = tp->minuslist = 0;
649 if (astr == NULL || sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell) <= 0) {
657 ParseAcl (char *astr)
659 int nplus, nminus, i, trights, ret;
661 struct AclEntry *first, *next, *last, *tl;
665 if (astr == NULL || strlen(astr) == 0)
668 ret = sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
673 astr = SkipLine(astr);
674 ret = sscanf(astr, "%d", &ta->nminus);
679 astr = SkipLine(astr);
686 for(i=0;i<nplus;i++) {
687 ret = sscanf(astr, "%100s %d", tname, &trights);
690 astr = SkipLine(astr);
691 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
696 strcpy(tl->name, tname);
697 tl->rights = trights;
703 ta->pluslist = first;
707 for(i=0;i<nminus;i++) {
708 ret = sscanf(astr, "%100s %d", tname, &trights);
711 astr = SkipLine(astr);
712 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
717 strcpy(tl->name, tname);
718 tl->rights = trights;
724 ta->minuslist = first;
729 for (;first; first = next) {
733 first = ta->pluslist;
736 for (;first; first = next) {
744 /* clean up an access control list of its bad entries; return 1 if we made
745 any changes to the list, and 0 otherwise */
746 extern "C" int CleanAcl(struct Acl *aa)
748 register struct AclEntry *te, **le, *ne;
753 /* Don't correct DFS ACL's for now */
757 /* prune out bad entries */
758 changes = 0; /* count deleted entries */
760 for(te = aa->pluslist; te; te = ne) {
762 if (BadName(te->name)) {
775 for(te = aa->minuslist; te; te = ne) {
777 if (BadName(te->name)) {
791 void CleanACL(CStringArray& names)
794 register struct Acl *ta;
795 struct ViceIoctl blob;
798 ShowMessageBox(IDS_CLEANACL_MSG, MB_OK|MB_ICONINFORMATION, IDS_CLEANACL_MSG);
802 for (int i = 0; i < names.GetSize(); i++) {
803 blob.out_size = MAXSIZE;
807 code = pioctl_T(names[i], VIOCGETAL, &blob, 1);
809 ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONERROR, 0, names[i], GetAfsError(errno));
813 ta = ParseAcl(space);
815 ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
819 ShowMessageBox(IDS_CLEANACL_NOT_SUPPORTED, MB_ICONERROR, IDS_CLEANACL_NOT_SUPPORTED, names[i]);
823 changes = CleanAcl(ta);
827 /* now set the acl */
828 blob.in = AclToString(ta);
829 blob.in_size = strlen((char *)blob.in) + 1;
832 code = pioctl_T(names[i], VIOCSETAL, &blob, 1);
834 if (errno == EINVAL) {
835 ShowMessageBox(IDS_CLEANACL_INVALID_ARG, MB_ICONERROR, IDS_CLEANACL_INVALID_ARG, names[i]);
839 ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONERROR, 0, names[i], GetAfsError(errno));
846 // Derived from fs.c's ListAclCmd
847 BOOL GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& strNegative)
850 register struct Acl *ta;
851 struct ViceIoctl blob;
853 int idf = 0; //getidf(as, parm_listacl_id);
857 blob.out_size = MAXSIZE;
859 blob.in = blob.out = space;
861 code = pioctl_T(strDir, VIOCGETAL, &blob, 1);
863 ShowMessageBox(IDS_GETRIGHTS_ERROR, MB_ICONERROR, IDS_GETRIGHTS_ERROR, strDir, GetAfsError(errno));
867 ta = ParseAcl(space);
869 ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
873 ShowMessageBox(IDS_DFSACL_ERROR, MB_ICONERROR, IDS_DFSACL_ERROR);
878 // printf(" Default cell = %s\n", ta->cell);
883 for (te = ta->pluslist; te; te = te->next) {
884 strNormal.Add(te->name);
885 strNormal.Add(GetRightsString(te->rights, ta->dfs));
889 if (ta->nminus > 0) {
890 for (te = ta->minuslist; te; te = te->next) {
891 strNegative.Add(te->name);
892 strNegative.Add(GetRightsString(te->rights, ta->dfs));
899 struct AclEntry *FindList(register struct AclEntry *pCurEntry, const char *entryName)
902 if (!foldcmp(pCurEntry->name, PCCHAR(entryName)))
904 pCurEntry = pCurEntry->next;
910 void ChangeList(struct Acl *pAcl, BYTE bNormalRights, const CString & entryName, LONG nEntryRights)
915 struct AclEntry *pEntry;
916 CStringUtf8 uEntryName(entryName);
920 pEntry = (bNormalRights ? pAcl->pluslist : pAcl->minuslist);
921 pEntry = FindList(pEntry, uEntryName);
923 /* Found the item already in the list. */
925 pEntry->rights = nEntryRights;
927 pAcl->nplus -= PruneList(&pAcl->pluslist, pAcl->dfs);
929 pAcl->nminus -= PruneList(&pAcl->minuslist, pAcl->dfs);
933 /* Otherwise we make a new item and plug in the new data. */
934 pEntry = (struct AclEntry *) malloc(sizeof (struct AclEntry));
937 strcpy(pEntry->name, uEntryName);
938 pEntry->rights = nEntryRights;
941 pEntry->next = pAcl->pluslist;
942 pAcl->pluslist = pEntry;
944 if (nEntryRights == 0 || nEntryRights == -1)
945 pAcl->nplus -= PruneList(&pAcl->pluslist, pAcl->dfs);
948 pEntry->next = pAcl->minuslist;
949 pAcl->minuslist = pEntry;
951 if (nEntryRights == 0)
952 pAcl->nminus -= PruneList(&pAcl->minuslist, pAcl->dfs);
956 enum rtype {add, destroy, deny};
958 static LONG Convert(const CString& strRights, int dfs, enum rtype *rtypep)
963 *rtypep = add; /* add rights, by default */
965 if (strRights == _T("read"))
966 return PRSFS_READ | PRSFS_LOOKUP;
967 if (strRights == _T("write"))
968 return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
969 if (strRights == _T("mail"))
970 return PRSFS_INSERT | PRSFS_LOCK | PRSFS_LOOKUP;
971 if (strRights == _T("all"))
972 return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
974 if (strRights == _T("none")) {
975 *rtypep = destroy; /* Remove entire entry */
979 len = strRights.GetLength();
982 for (i = 0; i < len; i++) {
983 TCHAR c = strRights[i];
984 if (c == _T('r')) mode |= PRSFS_READ;
985 else if (c == _T('l')) mode |= PRSFS_LOOKUP;
986 else if (c == _T('i')) mode |= PRSFS_INSERT;
987 else if (c == _T('d')) mode |= PRSFS_DELETE;
988 else if (c == _T('w')) mode |= PRSFS_WRITE;
989 else if (c == _T('k')) mode |= PRSFS_LOCK;
990 else if (c == _T('a')) mode |= PRSFS_ADMINISTER;
992 fprintf(stderr, "illegal rights character '%c'.\n", c);
999 BOOL SaveACL(const CString& strCellName, const CString& strDir, const CStringArray& normal, const CStringArray& negative)
1002 struct ViceIoctl blob;
1007 HOURGLASS hourglass;
1010 pAcl = EmptyAcl(strCellName);
1012 // Set its normal rights
1014 for (i = 0; i < normal.GetSize(); i += 2) {
1015 rights = Convert(normal[i + 1], 0, &rtype);
1016 ChangeList(pAcl, TRUE, normal[i], rights);
1019 // Set its negative rights
1020 for (i = 0; i < negative.GetSize(); i += 2) {
1021 rights = Convert(negative[i + 1], 0, &rtype);
1022 ChangeList(pAcl, FALSE, negative[i], rights);
1026 blob.in = AclToString(pAcl);
1028 blob.in_size = 1 + strlen((const char *)blob.in);
1030 code = pioctl_T(strDir, VIOCSETAL, &blob, 1);
1032 if (errno == EINVAL)
1033 ShowMessageBox(IDS_SAVE_ACL_EINVAL_ERROR, MB_ICONERROR, IDS_SAVE_ACL_EINVAL_ERROR, strDir);
1035 ShowMessageBox(IDS_SAVE_ACL_ERROR, MB_ICONERROR, IDS_SAVE_ACL_ERROR, strDir, GetAfsError(errno, strDir));
1043 BOOL CopyACL(const CString& strToDir, const CStringArray& normal, const CStringArray& negative, BOOL bClear)
1046 struct ViceIoctl blob;
1048 int idf = 0; // getidf(as, parm_copyacl_id);
1050 HOURGLASS hourglass;
1052 // Get ACL to copy to
1053 blob.out_size = MAXSIZE;
1055 blob.in = blob.out = space;
1057 code = pioctl_T(strToDir, VIOCGETAL, &blob, 1);
1059 ShowMessageBox(IDS_ACL_READ_ERROR, MB_ICONERROR, IDS_ACL_READ_ERROR, strToDir, GetAfsError(errno, strToDir));
1064 pToAcl = EmptyAcl(space);
1066 pToAcl = ParseAcl(space);
1068 if (pToAcl == NULL) {
1069 ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
1076 ShowMessageBox(IDS_NO_DFS_COPY_ACL, MB_ICONERROR, IDS_NO_DFS_COPY_ACL, strToDir);
1083 // Set normal rights
1085 for (i = 0; i < normal.GetSize(); i += 2) {
1086 LONG rights = Convert(normal[i + 1], 0, &rtype);
1087 ChangeList(pToAcl, TRUE, normal[i], rights);
1090 // Set negative rights
1091 for (i = 0; i < negative.GetSize(); i += 2) {
1092 LONG rights = Convert(negative[i + 1], 0, &rtype);
1093 ChangeList(pToAcl, FALSE, normal[i], rights);
1096 // Save modified ACL
1097 blob.in = AclToString(pToAcl);
1099 blob.in_size = 1 + strlen((char *)blob.in);
1101 code = pioctl_T(strToDir, VIOCSETAL, &blob, 1);
1104 if (errno == EINVAL)
1105 ShowMessageBox(IDS_COPY_ACL_EINVAL_ERROR, MB_ICONERROR, IDS_COPY_ACL_EINVAL_ERROR, strToDir);
1107 ShowMessageBox(IDS_COPY_ACL_ERROR, MB_ICONERROR, IDS_COPY_ACL_ERROR, strToDir, GetAfsError(errno, strToDir));
1113 ShowMessageBox(IDS_COPY_ACL_OK, MB_OK|MB_ICONINFORMATION, IDS_COPY_ACL_OK);
1118 CString ParseMountPoint(const CString strFile, CString strMountPoint)
1123 CString strMountPointInfo;
1125 if (strMountPoint[0] == '#')
1126 strType = "Regular";
1127 else if (strMountPoint[0] == '%')
1128 strType = "Read/Write";
1130 int nColon = strMountPoint.Find(':');
1132 strCell = strMountPoint.Mid(1, nColon - 1);
1133 strVolume = strMountPoint.Mid(nColon + 1);
1135 strVolume = strMountPoint.Mid(1);
1137 strMountPointInfo = strFile + _T("\t") + strVolume + _T("\t") + strCell + _T("\t") + strType;
1139 return strMountPointInfo;
1142 CString ParseSymlink(const CString strFile, CString strSymlink)
1144 CString strSymlinkInfo;
1146 strSymlinkInfo = strFile + _T("\t") + strSymlink;
1148 return strSymlinkInfo;
1151 BOOL IsPathInAfs(const CString & strPath)
1153 struct ViceIoctl blob;
1156 HOURGLASS hourglass;
1160 debugBuf.Format(_T("IsPathInAfs(%s)"), strPath);
1161 OutputDebugString(debugBuf);
1164 blob.out_size = MAXSIZE;
1167 code = pioctl_T(strPath, VIOC_FILE_CELL_NAME, &blob, 1);
1169 debugBuf.Format(_T("VIOC_FILE_CELL_NAME=%d"), code);
1170 OutputDebugString(debugBuf);
1173 if ((errno == EINVAL) || (errno == ENOENT))
1180 IsFreelanceRoot(const CString& apath)
1182 struct ViceIoctl blob;
1186 blob.out_size = MAXSIZE;
1189 code = pioctl_T(apath, VIOC_FILE_CELL_NAME, &blob, 1);
1191 return !strcmp("Freelance.Local.Root",space);
1192 return 1; /* assume it is because it is more restrictive that way */
1195 static const char * NetbiosName(void)
1197 static char buffer[1024] = "AFS";
1203 code = RegOpenKeyExA(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
1204 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey);
1205 if (code == ERROR_SUCCESS) {
1206 dummyLen = sizeof(buffer);
1207 code = RegQueryValueExA(parmKey, "NetbiosName", NULL, NULL,
1208 (LPBYTE)buffer, &dummyLen);
1209 RegCloseKey (parmKey);
1211 strcpy(buffer, "AFS");
1216 static void FixNetbiosPath(CString& path)
1218 if (!IsPathInAfs(path)) {
1220 const char * nbname = NetbiosName();
1223 nbroot.Format(_T("\\\\%S\\"), nbname);
1225 nbroot.Format(_T("\\\\%s\\"), nbname);
1228 if (nbroot.CompareNoCase(path) == 0) {
1229 path.Append(_T("all\\"));
1234 #define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins"
1236 static BOOL IsAdmin (void)
1238 static BOOL fAdmin = FALSE;
1239 static BOOL fTested = FALSE;
1243 /* Obtain the SID for the AFS client admin group. If the group does
1244 * not exist, then assume we have AFS client admin privileges.
1246 PSID psidAdmin = NULL;
1247 DWORD dwSize, dwSize2;
1248 TCHAR pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ];
1249 TCHAR *pszRefDomain = NULL;
1250 SID_NAME_USE snu = SidTypeGroup;
1252 dwSize = sizeof(pszAdminGroup);
1254 if (!GetComputerName(pszAdminGroup, &dwSize)) {
1255 /* Can't get computer name. We return false in this case.
1256 Retain fAdmin and fTested. This shouldn't happen.*/
1263 lstrcat(pszAdminGroup, _T("\\"));
1264 lstrcat(pszAdminGroup, _T(AFSCLIENT_ADMIN_GROUPNAME));
1266 LookupAccountName(NULL, pszAdminGroup, NULL, &dwSize, NULL, &dwSize2, &snu);
1267 /* that should always fail. */
1269 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
1270 /* if we can't find the group, then we allow the operation */
1275 if (dwSize == 0 || dwSize2 == 0) {
1281 psidAdmin = (PSID)malloc(dwSize); memset(psidAdmin,0,dwSize);
1282 pszRefDomain = (TCHAR *)malloc(dwSize2);
1284 if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) {
1285 /* We can't lookup the group now even though we looked it up earlier.
1286 Could this happen? */
1289 /* Then open our current ProcessToken */
1292 if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken))
1295 if (!CheckTokenMembership(hToken, psidAdmin, &fAdmin)) {
1296 /* We'll have to allocate a chunk of memory to store the list of
1297 * groups to which this user belongs; find out how much memory
1301 PTOKEN_GROUPS pGroups;
1303 GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize);
1305 pGroups = (PTOKEN_GROUPS)malloc(dwSize);
1307 /* Allocate that buffer, and read in the list of groups. */
1308 if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize))
1310 /* Look through the list of group SIDs and see if any of them
1311 * matches the AFS Client Admin group SID.
1314 for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup)
1316 if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) {
1326 /* if do not have permission because we were not explicitly listed
1327 * in the Admin Client Group let's see if we are the SYSTEM account
1330 PTOKEN_USER pTokenUser;
1331 SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
1332 PSID pSidLocalSystem = 0;
1335 GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
1337 pTokenUser = (PTOKEN_USER)malloc(dwSize);
1339 if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize))
1340 gle = GetLastError();
1342 if (AllocateAndInitializeSid( &SIDAuth, 1,
1343 SECURITY_LOCAL_SYSTEM_RID,
1344 0, 0, 0, 0, 0, 0, 0,
1347 if (EqualSid(pTokenUser->User.Sid, pSidLocalSystem)) {
1351 FreeSid(pSidLocalSystem);
1369 CString Parent(const CString& path)
1371 int last_slash = path.ReverseFind(_T('\\'));
1373 if (last_slash != -1) {
1374 CString ret = path.Left(last_slash + 1);
1377 if (path.GetLength() >= 2 && path[1] == _T(':')) {
1378 CString ret = path.Left(2);
1379 ret.AppendChar(_T('.'));
1382 CString ret = _T(".");
1388 CString LastComponent(const CString& path)
1390 int last_slash = path.ReverseFind(_T('\\'));
1392 if (last_slash != -1) {
1393 CString ret = path.Mid(last_slash + 1);
1396 if (path.GetLength() >= 2 && path[1] == _T(':')) {
1397 CString ret = path.Mid(2);
1407 GetCell(const CString & path)
1409 char cellname[MAXCELLCHARS];
1411 struct ViceIoctl blob;
1414 blob.out_size = sizeof(cellname);
1415 blob.out = cellname;
1417 code = pioctl_T(path, VIOC_FILE_CELL_NAME, &blob, 1);
1424 return Utf8ToCString(cellname);
1429 BOOL ListMount(CStringArray& files)
1432 struct ViceIoctl blob;
1435 CString parent_dir; /* Parent directory of true name */
1436 CStringUtf8 last_component; /* Last component of true name */
1438 CStringArray mountPoints;
1440 HOURGLASS hourglass;
1444 for (int i = 0; i < files.GetSize(); i++) {
1445 int last_slash = files[i].ReverseFind(_T('\\'));
1447 if (last_slash != -1) {
1448 last_component.SetString( files[i].Mid(last_slash + 1) );
1449 parent_dir.SetString( files[i].Left(last_slash + 1) );
1450 FixNetbiosPath(parent_dir);
1452 // The path is of the form "C:foo" or just "foo". If
1453 // there is a drive, then use the current directory of
1454 // that drive. Otherwise we just use '.'.
1456 if (files[i].GetLength() >= 2 && files[i][1] == _T(':')) {
1457 parent_dir.Format(_T("%c:."), files[i][0]);
1458 last_component.SetString( files[i].Mid(2) );
1460 parent_dir.SetString( _T("."));
1461 last_component.SetString( files[i] );
1465 blob.in_size = last_component.GetLength() + 1;
1466 blob.in = last_component.GetBuffer();
1467 blob.out_size = MAXSIZE;
1469 memset(space, 0, MAXSIZE);
1471 code = pioctl_T(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
1473 last_component.ReleaseBuffer();
1476 int nPos = strlen(space) - 1;
1477 if (space[nPos] == '.')
1479 mountPoints.Add(ParseMountPoint(StripPath(files[i]), Utf8ToCString(space)));
1482 if (errno == EINVAL)
1483 mountPoints.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(files[i])));
1485 mountPoints.Add(GetMessageString(IDS_LIST_MOUNT_POINT_ERROR, GetAfsError(errno, StripPath(files[i]))));
1489 CMountPointsDlg dlg;
1490 dlg.SetMountPoints(mountPoints);
1497 MakeMount(const CString& strDir,
1498 const CString& strVolName,
1499 const CString& strInCellName,
1503 struct ViceIoctl blob;
1504 HOURGLASS hourglass;
1506 ASSERT(strVolName.GetLength() < 64);
1508 CString strParent = Parent(strDir);
1510 FixNetbiosPath(strParent);
1511 if (!IsPathInAfs(strParent)) {
1512 ShowMessageBox(IDS_MAKE_MP_NOT_AFS_ERROR, MB_ICONERROR, IDS_MAKE_MP_NOT_AFS_ERROR);
1516 CString strPath = strParent + LastComponent(strDir);
1518 if ( IsFreelanceRoot(strParent) && !IsAdmin() ) {
1519 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR,
1520 IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
1526 strMount.Format(_T("%c%s%s%s."),
1527 ((bRW)?_T('%'):_T('#')),
1529 ((strInCellName.IsEmpty())?_T(""):_T(":")),
1532 CStringUtf8 ustrMount(strMount);
1535 blob.in_size = ustrMount.GetLength() + 1;
1536 blob.in = ustrMount.GetBuffer();
1539 code = pioctl_T(strPath, VIOC_AFS_CREATE_MT_PT, &blob, 0);
1541 ustrMount.ReleaseBuffer();
1544 ShowMessageBox(IDS_MOUNT_POINT_ERROR, MB_ICONERROR, IDS_MOUNT_POINT_ERROR, GetAfsError(errno, strDir));
1553 long fs_ExtractDriveLetter(const char *inPathp, char *outPathp)
1555 if (inPathp[0] != 0 && inPathp[1] == ':') {
1556 /* there is a drive letter */
1557 *outPathp++ = *inPathp++;
1558 *outPathp++ = *inPathp++;
1566 /* strip the drive letter from a component */
1567 long fs_StripDriveLetter(const char *inPathp, char *outPathp, long outSize)
1569 char tempBuffer[1000];
1570 strcpy(tempBuffer, inPathp);
1571 if (tempBuffer[0] != 0 && tempBuffer[1] == ':') {
1572 /* drive letter present */
1573 strcpy(outPathp, tempBuffer+2);
1576 /* no drive letter present */
1577 strcpy(outPathp, tempBuffer);
1583 BOOL RemoveSymlink(const CString& strName)
1587 struct ViceIoctl blob;
1588 char lsbuffer[1024];
1590 HOURGLASS hourglass;
1592 CString strParent = Parent(strName);
1593 CStringUtf8 ustrLast(LastComponent(strName));
1594 FixNetbiosPath(strParent);
1596 if ( IsFreelanceRoot(strParent) && !IsAdmin() ) {
1597 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
1601 blob.in_size = ustrLast.GetLength() + 1;
1602 blob.in = ustrLast.GetBuffer();
1603 blob.out = lsbuffer;
1604 blob.out_size = sizeof(lsbuffer);
1605 code = pioctl_T(strParent, VIOC_LISTSYMLINK, &blob, 0);
1606 ustrLast.ReleaseBuffer();
1610 blob.in_size = ustrLast.GetLength() + 1;
1611 blob.in = ustrLast.GetBuffer();
1613 code = pioctl_T(strParent, VIOC_DELSYMLINK, &blob, 0);
1615 ustrLast.ReleaseBuffer();
1620 BOOL IsSymlink(const CString& strName)
1622 struct ViceIoctl blob;
1625 HOURGLASS hourglass;
1629 str.Format(_T("IsSymlink(%s)"), strName);
1630 OutputDebugString(str);
1633 CStringUtf8 ustrLast(LastComponent(strName));
1634 CString strParent = Parent(strName);
1636 FixNetbiosPath(strParent);
1638 blob.in_size = ustrLast.GetLength() + 1;
1639 blob.in = ustrLast.GetBuffer();
1640 blob.out_size = MAXSIZE;
1642 memset(space, 0, MAXSIZE);
1644 code = pioctl_T(strParent, VIOC_LISTSYMLINK, &blob, 1);
1646 ustrLast.ReleaseBuffer();
1652 BOOL IsMountPoint(const CString& path)
1654 register LONG code = 0;
1655 struct ViceIoctl blob;
1656 char lsbuffer[1024];
1658 HOURGLASS hourglass;
1662 str.Format(_T("IsMountPoint(%s)"), path);
1663 OutputDebugString(str);
1666 CString parent = Parent(path);
1667 FixNetbiosPath(parent);
1669 CStringUtf8 mountpoint(LastComponent(path));
1674 str.Format(_T("last_component=%S"), mountpoint);
1676 str.Format(_T("last_component=%s"), mountpoint);
1678 OutputDebugString(str);
1681 blob.in_size = mountpoint.GetLength() + 1;
1682 blob.in = mountpoint.GetBuffer();
1683 blob.out = lsbuffer;
1684 blob.out_size = sizeof(lsbuffer);
1686 code = pioctl_T(parent, VIOC_AFS_STAT_MT_PT, &blob, 0);
1688 mountpoint.ReleaseBuffer();
1695 * Delete AFS mount points. Variables are used as follows:
1696 * tbuffer: Set to point to the null-terminated directory name of the mount point
1697 * (or ``.'' if none is provided)
1698 * tp: Set to point to the actual name of the mount point to nuke.
1700 BOOL RemoveMount(CStringArray& files)
1702 register LONG code = 0;
1703 struct ViceIoctl blob;
1705 CStringArray results;
1709 HOURGLASS hourglass;
1711 for (int i = 0; i < files.GetSize(); i++) {
1712 if (!IsMountPoint(files[i])) {
1714 if (errno == EINVAL)
1715 results.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(files[i])));
1717 results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
1718 continue; // don't bother trying
1721 CString parent = Parent(files[i]);
1722 CStringUtf8 mountpoint(LastComponent(files[i]));
1723 FixNetbiosPath(parent);
1725 if ( IsFreelanceRoot(parent) && !IsAdmin() ) {
1726 results.Add(GetMessageString(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, StripPath(files[i])));
1728 continue; /* skip */
1732 blob.in_size = mountpoint.GetLength() + 1;
1733 blob.in = mountpoint.GetBuffer();
1735 code = pioctl_T(parent, VIOC_AFS_DELETE_MT_PT, &blob, 0);
1737 mountpoint.ReleaseBuffer();
1741 results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
1743 results.Add(GetMessageString(IDS_DELETED));
1746 LoadString (str, IDS_REMOVE_MP);
1747 LoadString (str2, IDS_REMOVE_MP_COLUMN);
1748 CResultsDlg dlg(REMOVE_MOUNT_POINTS_HELP_ID);
1749 dlg.SetContents(str, str2, StripPath(files), results);
1755 BOOL GetVolumeInfo(CString strFile, CVolInfo& volInfo)
1758 struct ViceIoctl blob;
1759 struct VolumeStatus *status;
1762 HOURGLASS hourglass;
1764 volInfo.m_strFilePath = strFile;
1765 volInfo.m_strFileName = StripPath(strFile);
1768 volInfo.m_strName = "VolumeName";
1770 volInfo.m_nQuota = 20 * 1024 * 1024;
1771 volInfo.m_nNewQuota = volInfo.m_nQuota;
1772 volInfo.m_nUsed = volInfo.m_nQuota / 2;
1773 volInfo.m_nPartSize = 50 * 1024 * 1024;
1774 volInfo.m_nPartFree = 30 * 1024 * 1024;
1775 volInfo.m_nDup = -1;
1779 blob.out_size = MAXSIZE;
1783 code = pioctl_T(strFile, VIOCGETVOLSTAT, &blob, 1);
1785 volInfo.m_strErrorMsg = GetAfsError(errno, strFile);
1789 status = (VolumeStatus *)space;
1790 name = (char *)status + sizeof(*status);
1792 volInfo.m_strName = Utf8ToCString(name);
1793 volInfo.m_nID = status->Vid;
1794 volInfo.m_nQuota = status->MaxQuota;
1795 volInfo.m_nNewQuota = status->MaxQuota;
1796 volInfo.m_nUsed = status->BlocksInUse;
1797 volInfo.m_nPartSize = status->PartMaxBlocks;
1798 volInfo.m_nPartFree = status->PartBlocksAvail;
1799 volInfo.m_nDup = -1;
1804 BOOL SetVolInfo(CVolInfo& volInfo)
1807 struct ViceIoctl blob;
1808 struct VolumeStatus *status;
1811 HOURGLASS hourglass;
1813 blob.out_size = MAXSIZE;
1814 blob.in_size = sizeof(*status) + 3; /* for the three terminating nulls */
1818 status = (VolumeStatus *)space;
1819 status->MinQuota = -1;
1820 status->MaxQuota = volInfo.m_nNewQuota;
1822 input = (char *)status + sizeof(*status);
1823 *(input++) = '\0'; /* never set name: this call doesn't change vldb */
1824 *(input++) = '\0'; // No offmsg
1825 *(input++) = '\0'; // No motd
1828 FILE *fp = OpenFile(szLogFileName, "a");
1830 fprintf(fp, "\nSetVolInfo() pioctl parms:\n");
1831 fprintf(fp, "\tpathp = %s\n\topcode = VIOCSETVOLSTAT (%d)\n\tblobp = %ld\n", PCCHAR(volInfo.m_strFilePath), VIOCSETVOLSTAT, &blob);
1832 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);
1833 fprintf(fp, "\t\t\tstatus->MinQuota = %ld\n", status->MinQuota);
1834 fprintf(fp, "\t\t\tstatus->MaxQuota = %ld\n", status->MaxQuota);
1835 fprintf(fp, "\t\t\tOther status fields aren't set\n");
1836 fprintf(fp, "\t\t\t3 nulls follow the VolumeStatus structure.\n");
1837 fprintf(fp, "\tfollow = 1\n");
1842 code = pioctl_T(volInfo.m_strFilePath, VIOCSETVOLSTAT, &blob, 1);
1844 ShowMessageBox(IDS_SET_QUOTA_ERROR, MB_ICONERROR, IDS_SET_QUOTA_ERROR, GetAfsError(errno, volInfo.m_strName));
1851 void GetCellName(const CString& cellNamep, struct afsconf_cell *infop)
1853 CStringUtf8 uCellName(cellNamep);
1855 StringCbCopyA(infop->name, sizeof(infop->name), uCellName);
1858 BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast)
1861 struct ViceIoctl blob;
1864 struct afsconf_cell info;
1865 struct chservinfo checkserv;
1867 HOURGLASS hourglass;
1869 memset(&checkserv, 0, sizeof(struct chservinfo));
1870 blob.in_size = sizeof(struct chservinfo);
1871 blob.in = (caddr_t)&checkserv;
1873 blob.out_size = MAXSIZE;
1875 memset(space, 0, sizeof(afs_int32)); /* so we assure zero when nothing is copied back */
1877 if (nCellsToCheck == SPECIFIC_CELL) {
1879 GetCellName(strCellName, &info);
1880 strcpy(checkserv.tbuffer,info.name);
1881 checkserv.tsize = strlen(info.name) + 1;
1883 if (nCellsToCheck != ALL_CELLS)
1885 strcpy(checkserv.tbuffer, "\0");
1886 checkserv.tsize = 0;
1889 temp |= 1; /* set fast flag */
1891 checkserv.magic = 0x12345678; /* XXX */
1892 checkserv.tflags = temp;
1893 checkserv.tinterval = -1; /* don't change current interval */
1895 code = pioctl_utf8(0, VIOCCKSERV, &blob, 1);
1897 ShowMessageBox(IDS_CHECK_SERVERS_ERROR, MB_ICONERROR, IDS_CHECK_SERVERS_ERROR, GetAfsError(errno, CString()));
1901 memcpy(&temp, space, sizeof(LONG));
1904 ShowMessageBox(IDS_ALL_SERVERS_RUNNING, MB_OK|MB_ICONINFORMATION, IDS_ALL_SERVERS_RUNNING);
1908 CStringArray servers;
1909 for (j = 0; j < MAXHOSTS; j++) {
1910 memcpy(&temp, space + j * sizeof(LONG), sizeof(LONG));
1914 char *name = hostutil_GetNameByINet(temp);
1918 CDownServersDlg dlg;
1919 dlg.SetServerNames(servers);
1925 BOOL GetTokenInfo(CStringArray& tokenInfo)
1929 time_t current_time;
1930 time_t tokenExpireTime;
1934 struct ktc_principal serviceName, clientName;
1935 struct ktc_token token;
1937 CString strTokenInfo;
1938 CString strUserName;
1939 CString strCellName;
1942 // tokenInfo.Add("");
1946 HOURGLASS hourglass;
1948 // printf("\nTokens held by the Cache Manager:\n\n");
1950 current_time = time(0);
1953 rc = ktc_ListTokens(cellNum, &cellNum, &serviceName);
1954 if (rc == KTC_NOENT) {
1956 // printf(" --End of list --\n");
1959 else if (rc == KTC_NOCM) {
1960 ShowMessageBox(IDS_GET_TOKENS_NO_AFS_SERVICE);
1961 // printf("AFS service may not have started\n");
1965 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR, MB_ICONERROR, IDS_GET_TOKENS_UNEXPECTED_ERROR, rc);
1967 // printf("Unexpected error, code %d\n", rc);
1971 rc = ktc_GetToken(&serviceName, &token, sizeof(token), &clientName);
1973 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR2, MB_ICONERROR, IDS_GET_TOKENS_UNEXPECTED_ERROR2,
1974 serviceName.name, serviceName.instance, serviceName.cell, rc);
1978 tokenExpireTime = token.endTime;
1980 strcpy(userName, clientName.name);
1981 if (clientName.instance[0] != 0) {
1982 strcat(userName, ".");
1983 strcat(userName, clientName.instance);
1986 BOOL bShowName = FALSE;
1988 if (userName[0] == '\0')
1989 ; //printf("Tokens");
1990 // AFS ID is not returned at this time.
1991 // else if (strncmp(userName, "AFS ID", 6) == 0)
1992 // printf("User's (%s) tokens", userName);
1993 // sscanf(userName, "(AFS ID %s)", szAfsID);
1994 else if (strncmp(userName, "Unix UID", 8) == 0)
1995 ; //printf("Tokens");
1997 strUserName = userName;
1998 // printf("User %s's tokens", userName);
2000 // printf(" for %s%s%s@%s ", serviceName.name, serviceName.instance[0] ? "." : "", serviceName.instance, serviceName.cell);
2001 strCellName = serviceName.cell;
2003 if (tokenExpireTime <= current_time)
2004 strExpir = "[>> Expired <<]";
2005 // printf("[>> Expired <<]\n");
2007 expireString = ctime(&tokenExpireTime);
2008 expireString += 4; /* Skip day of week */
2009 expireString[12] = '\0'; /* Omit secs & year */
2010 // printf("[Expires %s]\n", expireString);
2012 strExpir.Format(_T("%S"), expireString);
2014 strExpir.Format(_T("%s"), expireString);
2018 strTokenInfo = strUserName + "\t" + strCellName + "\t" + strExpir + "\t" + strCellName;
2019 tokenInfo.Add(strTokenInfo);
2023 // printf("Press <Enter> or <Return> when finished: ");
2028 UINT MakeSymbolicLink(const CString& strName, const CString& strTarget)
2030 struct ViceIoctl blob;
2032 HOURGLASS hourglass;
2034 CString strParent = Parent(strName);
2035 FixNetbiosPath(strParent);
2039 str.Format(_T("MakeSymbolicLink: name = %s target = %s parent = %s\n"),
2040 strName, strTarget, strParent);
2041 OutputDebugString(str);
2044 if ( IsFreelanceRoot(strParent) && !IsAdmin() ) {
2045 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
2049 CStringUtf8 ustrTarget(strTarget);
2051 blob.in_size = ustrTarget.GetLength() + 1;
2052 blob.in = ustrTarget.GetBuffer();
2056 code = pioctl_T(strName, VIOC_SYMLINK, &blob, 0);
2058 ustrTarget.ReleaseBuffer();
2065 void ListSymbolicLinkPath(const char *strName,char *strPath,UINT nlenPath)
2067 ASSERT(nlenPath<MAX_PATH);
2068 struct ViceIoctl blob;
2069 char orig_name[MAX_PATH+1]; /*Original name, may be modified*/
2070 char true_name[MAX_PATH+1]; /*``True'' dirname (e.g., symlink target)*/
2071 char parent_dir[MAX_PATH+1]; /*Parent directory of true name*/
2072 char *last_component; /*Last component of true name*/
2075 HOURGLASS hourglass;
2077 strcpy(orig_name, strName);
2078 strcpy(true_name, orig_name);
2080 * Find rightmost slash, if any.
2082 last_component = (char *) strrchr(true_name, '\\');
2083 if (!last_component)
2084 last_component = (char *) strrchr(true_name, '/');
2085 if (last_component) {
2087 * Found it. Designate everything before it as the parent directory,
2088 * everything after it as the final component.
2090 strncpy(parent_dir, true_name, last_component - true_name + 1);
2091 parent_dir[last_component - true_name + 1] = 0;
2092 last_component++; /*Skip the slash*/
2094 if (!IsPathInAfs(parent_dir)) {
2095 const char * nbname = NetbiosName();
2096 int len = strlen(nbname);
2098 if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
2099 parent_dir[len+2] == '\\' &&
2100 parent_dir[len+3] == '\0' &&
2101 !strnicmp(nbname,&parent_dir[2],len))
2103 sprintf(parent_dir,"\\\\%s\\all\\", nbname);
2109 * No slash appears in the given file name. Set parent_dir to the current
2110 * directory, and the last component as the given name.
2112 fs_ExtractDriveLetter(true_name, parent_dir);
2113 strcat(parent_dir, ".");
2114 last_component = true_name;
2115 fs_StripDriveLetter(true_name, true_name, sizeof(true_name));
2117 blob.in = last_component;
2118 blob.in_size = strlen(last_component)+1;
2119 blob.out_size = MAXSIZE;
2121 memset(space, 0, MAXSIZE);
2122 if ((code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1)))
2123 strcpy(space,"???");
2124 ASSERT(strlen(space)<MAX_PATH);
2125 strncpy(strPath,space,nlenPath);
2128 BOOL ListSymlink(CStringArray& files)
2131 struct ViceIoctl blob;
2133 CStringArray symlinks;
2135 HOURGLASS hourglass;
2139 for (int i = 0; i < files.GetSize(); i++) {
2141 CString strParent = Parent(files[i]);
2142 CStringUtf8 ustrLast(LastComponent(files[i]));
2144 FixNetbiosPath(strParent);
2146 blob.in_size = ustrLast.GetLength() + 1;
2147 blob.in = ustrLast.GetBuffer();
2148 blob.out_size = MAXSIZE;
2150 memset(space, 0, MAXSIZE);
2152 code = pioctl_T(strParent, VIOC_LISTSYMLINK, &blob, 1);
2154 ustrLast.ReleaseBuffer();
2157 CString syml = Utf8ToCString(space);
2158 int len = syml.GetLength();
2161 if (syml[len - 1] == _T('.'))
2162 syml.Truncate(len - 1);
2165 symlinks.Add(ParseSymlink(StripPath(files[i]), syml));
2169 if (errno == EINVAL)
2170 symlinks.Add(GetMessageString(IDS_NOT_SYMLINK_ERROR, StripPath(files[i])));
2172 symlinks.Add(GetMessageString(IDS_LIST_MOUNT_POINT_ERROR, GetAfsError(errno, StripPath(files[i]))));
2177 dlg.SetSymlinks(symlinks);