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 "symlinks_dlg.h"
28 #include "hourglass.h"
29 #include "down_servers_dlg.h"
32 #include <rx/rx_globals.h>
36 #include <afs/cellconfig.h>
37 #include <afs/vldbint.h>
38 #include <afs/volser.h>
40 #include <WINNT\afsreg.h>
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 VLDBInit(int noAuthFlag, struct afsconf_cell *info)
76 code = ugen_ClientInit(noAuthFlag, (char *)AFSDIR_CLIENT_ETC_DIRPATH,
77 info->name, 0, &uclient,
78 NULL, pn, rxkad_clear,
79 VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 50,
80 0, 0, USER_SERVICE_ID);
85 FILE *OpenFile(char *file, char *rwp)
92 code = GetWindowsDirectory(wdir, sizeof(wdir));
93 if (code == 0 || code > sizeof(wdir))
96 /* add trailing backslash, if required */
98 if (wdir[tlen - 1] != '\\')
103 fp = fopen(wdir, rwp);
108 CString StripPath(CString& strPath)
110 int nIndex = strPath.ReverseFind('\\');
112 CString strFile = strPath.Mid(nIndex + 1);
113 if (strFile.IsEmpty())
119 CStringArray& StripPath(CStringArray& files)
121 for (int i = 0; i < files.GetSize(); i++)
122 files[i] = StripPath(files[i]);
127 void Flush(const CStringArray& files)
130 struct ViceIoctl blob;
135 for (int i = 0; i < files.GetSize(); i++) {
136 blob.in_size = blob.out_size = 0;
138 code = pioctl(PCCHAR(files[i]), VIOCFLUSH, &blob, 0);
142 ShowMessageBox(IDS_FLUSH_FAILED, MB_ICONERROR, IDS_FLUSH_FAILED, files[i]);
144 ShowMessageBox(IDS_FLUSH_ERROR, MB_ICONERROR, IDS_FLUSH_ERROR, files[i], strerror(errno));
149 ShowMessageBox(IDS_FLUSH_OK, MB_ICONINFORMATION, IDS_FLUSH_OK);
152 void FlushVolume(const CStringArray& files)
155 struct ViceIoctl blob;
160 for (int i = 0; i < files.GetSize(); i++) {
161 blob.in_size = blob.out_size = 0;
163 code = pioctl(PCCHAR(files[i]), VIOC_FLUSHVOLUME, &blob, 0);
166 ShowMessageBox(IDS_FLUSH_VOLUME_ERROR, MB_ICONERROR, IDS_FLUSH_VOLUME_ERROR, files[i], strerror(errno));
171 ShowMessageBox(IDS_FLUSH_VOLUME_OK, MB_ICONINFORMATION, IDS_FLUSH_VOLUME_OK);
174 void WhichCell(CStringArray& files)
177 struct ViceIoctl blob;
182 CStringArray results;
188 for (int i = 0; i < files.GetSize(); i++) {
190 blob.out_size = MAXSIZE;
193 code = pioctl(PCCHAR(files[i]), VIOC_FILE_CELL_NAME, &blob, 1);
195 if (code == ENOENT) {
196 LoadString (str, IDS_CANT_GET_CELL);
199 results.Add(GetAfsError(errno));
204 LoadString (str, IDS_SHOW_CELL);
205 LoadString (str2, IDS_SHOW_CELL_COLUMN);
206 CResultsDlg dlg(SHOW_CELL_HELP_ID);
207 dlg.SetContents(str, str2, StripPath(files), results);
214 struct ViceIoctl blob;
219 blob.in = (char *) 0;
220 blob.out_size = MAXSIZE;
223 code = pioctl((char *) 0, VIOC_GET_WS_CELL, &blob, 1);
226 //Die(errno, (char *) 0);
229 //printf("This workstation belongs to cell '%s'\n", space);
235 struct ViceIoctl blob;
239 code = pioctl(0, VIOCCKBACK, &blob, 1);
241 ShowMessageBox(IDS_CHECK_VOLUMES_ERROR, MB_ICONERROR, IDS_CHECK_VOLUMES_ERROR, GetAfsError(errno, CString()));
245 ShowMessageBox(IDS_CHECK_VOLUMES_OK, MB_OK|MB_ICONINFORMATION, IDS_CHECK_VOLUMES_OK);
250 void SetCacheSizeCmd(LONG nNewCacheSize)
253 struct ViceIoctl blob;
257 blob.in = (char *) &nNewCacheSize;
258 blob.in_size = sizeof(LONG);
261 code = pioctl(0, VIOCSETCACHESIZE, &blob, 1);
263 // Die(errno, (char *) 0);
265 // printf("New cache size set.\n");
268 void WhereIs(CStringArray& files)
271 struct ViceIoctl blob;
272 CStringArray servers;
273 CStringArray resultFiles;
279 for (int i = 0; i < files.GetSize(); i++) {
280 blob.out_size = MAXSIZE;
283 memset(space, 0, sizeof(space));
285 code = pioctl(PCCHAR(files[i]), VIOCWHEREIS, &blob, 1);
287 resultFiles.Add(StripPath(files[i]));
288 servers.Add(GetAfsError(errno));
292 LONG *hosts = (LONG *)space;
296 for (int j = 0; j < MAXHOSTS; j++) {
299 char *hostName = hostutil_GetNameByINet(hosts[j]);
301 resultFiles.Add(StripPath(files[i]));
304 resultFiles.Add(" ");
305 servers.Add(hostName);
309 LoadString (str, IDS_SHOW_FS);
310 LoadString (str2, IDS_SHOW_FS_COLUMN);
311 CResultsDlg dlg(SHOW_FILE_SERVERS_HELP_ID);
312 dlg.SetContents(str, str2, resultFiles, servers);
317 CMtoUNIXerror(int cm_code)
320 case CM_ERROR_TIMEDOUT:
322 case CM_ERROR_NOACCESS:
324 case CM_ERROR_NOSUCHFILE:
330 case CM_ERROR_EXISTS:
332 case CM_ERROR_CROSSDEVLINK:
334 case CM_ERROR_NOTDIR:
338 case CM_ERROR_READONLY:
340 case CM_ERROR_WOULDBLOCK:
342 case CM_ERROR_NOSUCHCELL:
343 return ESRCH; /* hack */
344 case CM_ERROR_NOSUCHVOLUME:
345 return EPIPE; /* hack */
346 case CM_ERROR_NOMORETOKENS:
347 return EDOM; /* hack */
348 case CM_ERROR_TOOMANYBUFS:
349 return EFBIG; /* hack */
351 if (cm_code > 0 && cm_code < EILSEQ)
358 CString GetAfsError(int code, const char *filename)
362 code = CMtoUNIXerror(code);
364 if (code == EINVAL) {
366 strMsg.Format("Invalid argument; it is possible that the file is not in AFS");
368 strMsg.Format("Invalid argument");
369 } else if (code == ENOENT) {
371 strMsg.Format("The file does not exist");
373 strMsg.Format("No such file returned");
374 } else if (code == EROFS) {
375 strMsg.Format("You can not change a backup or readonly volume");
376 } else if (code == EACCES || code == EPERM) {
377 strMsg.Format("You do not have the required rights to do this operation");
378 } else if (code == ENODEV) {
379 strMsg.Format("AFS service may not have started");
380 } else if (code == ESRCH) {
381 strMsg.Format("Cell name not recognized");
382 } else if (code == ETIMEDOUT) {
383 strMsg.Format("Connection timed out");
384 } else if (code == EPIPE) {
385 strMsg.Format("Volume name or ID not recognized");
387 strMsg.Format("Error 0x%x occurred", code);
394 /************************************************************************
395 ************************** ACL Code *************************************
396 ************************************************************************/
398 typedef char sec_rgy_name_t[1025]; /* A DCE definition */
401 struct AclEntry *next;
407 int dfs; // Originally true if a dfs acl; now also the type
408 // of the acl (1, 2, or 3, corresponding to object,
409 // initial dir, or initial object).
410 sec_rgy_name_t cell; // DFS cell name
413 struct AclEntry *pluslist;
414 struct AclEntry *minuslist;
417 int foldcmp (register char *a, register char *b)
423 if (t >= 'A' && t <= 'Z') t += 0x20;
424 if (u >= 'A' && u <= 'Z') u += 0x20;
425 if (t != u) return 1;
426 if (t == 0) return 0;
430 extern "C" void ZapList(struct AclEntry *alist)
432 register struct AclEntry *tp, *np;
434 for (tp = alist; tp; tp = np) {
440 extern "C" void ZapAcl (struct Acl *acl)
442 ZapList(acl->pluslist);
443 ZapList(acl->minuslist);
447 extern "C" int PruneList (struct AclEntry **ae, int dfs)
449 struct AclEntry **lp = ae;
450 struct AclEntry *te, *ne;
453 for (te = *ae; te; te = ne) {
454 if ((!dfs && te->rights == 0) || te->rights == -1) {
469 char *SkipLine (register char *astr)
471 while (*astr != '\n')
479 /* tell if a name is 23 or -45 (digits or minus digits), which are bad names we must prune */
480 static int BadName(register char *aname)
484 /* all must be '-' or digit to be bad */
485 while (tc = *aname++) {
486 if ((tc != '-') && (tc < '0' || tc > '9'))
493 CString GetRightsString(register LONG arights, int dfs)
498 if (arights & PRSFS_READ) str += "r";
499 if (arights & PRSFS_LOOKUP) str += "l";
500 if (arights & PRSFS_INSERT) str += "i";
501 if (arights & PRSFS_DELETE) str += "d";
502 if (arights & PRSFS_WRITE) str += "w";
503 if (arights & PRSFS_LOCK) str += "k";
504 if (arights & PRSFS_ADMINISTER) str += "a";
508 if (arights & DFS_READ) str += "r"; else str += "-";
509 if (arights & DFS_WRITE) str += "w"; else printf("-");
510 if (arights & DFS_EXECUTE) str += "x"; else printf("-");
511 if (arights & DFS_CONTROL) str += "c"; else printf("-");
512 if (arights & DFS_INSERT) str += "i"; else printf("-");
513 if (arights & DFS_DELETE) str += "d"; else printf("-");
514 if (arights & (DFS_USRALL)) str += "+";
521 char *AclToString(struct Acl *acl)
523 static char mydata[MAXSIZE];
524 char tstring[MAXSIZE];
529 sprintf(dfsstring, " dfs:%d %s", acl->dfs, acl->cell);
532 sprintf(mydata, "%d%s\n%d\n", acl->nplus, dfsstring, acl->nminus);
534 for(tp = acl->pluslist; tp; tp = tp->next) {
535 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
536 strcat(mydata, tstring);
539 for(tp = acl->minuslist; tp; tp = tp->next) {
540 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
541 strcat(mydata, tstring);
547 struct Acl *EmptyAcl(const CString& strCellName)
549 register struct Acl *tp;
551 tp = (struct Acl *)malloc(sizeof (struct Acl));
552 tp->nplus = tp->nminus = 0;
553 tp->pluslist = tp->minuslist = 0;
555 strcpy(tp->cell, strCellName);
560 struct Acl *EmptyAcl(char *astr)
562 register struct Acl *tp;
565 tp = (struct Acl *)malloc(sizeof (struct Acl));
566 tp->nplus = tp->nminus = 0;
567 tp->pluslist = tp->minuslist = 0;
569 if (astr == NULL || sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell) <= 0) {
577 ParseAcl (char *astr)
579 int nplus, nminus, i, trights, ret;
581 struct AclEntry *first, *next, *last, *tl;
585 if (astr == NULL || strlen(astr) == 0)
588 ret = sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
593 astr = SkipLine(astr);
594 ret = sscanf(astr, "%d", &ta->nminus);
599 astr = SkipLine(astr);
606 for(i=0;i<nplus;i++) {
607 ret = sscanf(astr, "%100s %d", tname, &trights);
610 astr = SkipLine(astr);
611 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
616 strcpy(tl->name, tname);
617 tl->rights = trights;
623 ta->pluslist = first;
627 for(i=0;i<nminus;i++) {
628 ret = sscanf(astr, "%100s %d", tname, &trights);
631 astr = SkipLine(astr);
632 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
637 strcpy(tl->name, tname);
638 tl->rights = trights;
644 ta->minuslist = first;
650 for (;first; first = next) {
654 first = ta->pluslist;
657 for (;first; first = next) {
665 /* clean up an access control list of its bad entries; return 1 if we made
666 any changes to the list, and 0 otherwise */
667 extern "C" int CleanAcl(struct Acl *aa)
669 register struct AclEntry *te, **le, *ne;
674 /* Don't correct DFS ACL's for now */
678 /* prune out bad entries */
679 changes = 0; /* count deleted entries */
681 for(te = aa->pluslist; te; te = ne) {
683 if (BadName(te->name)) {
696 for(te = aa->minuslist; te; te = ne) {
698 if (BadName(te->name)) {
712 void CleanACL(CStringArray& names)
715 register struct Acl *ta;
716 struct ViceIoctl blob;
719 ShowMessageBox(IDS_CLEANACL_MSG, MB_OK|MB_ICONINFORMATION, IDS_CLEANACL_MSG);
723 for (int i = 0; i < names.GetSize(); i++) {
724 blob.out_size = MAXSIZE;
728 code = pioctl(PCCHAR(names[i]), VIOCGETAL, &blob, 1);
730 ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONERROR, 0, names[i], GetAfsError(errno));
734 ta = ParseAcl(space);
736 ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
740 ShowMessageBox(IDS_CLEANACL_NOT_SUPPORTED, MB_ICONERROR, IDS_CLEANACL_NOT_SUPPORTED, names[i]);
744 changes = CleanAcl(ta);
748 /* now set the acl */
749 blob.in = AclToString(ta);
750 blob.in_size = strlen((char *)blob.in) + 1;
753 code = pioctl(PCCHAR(names[i]), VIOCSETAL, &blob, 1);
755 if (errno == EINVAL) {
756 ShowMessageBox(IDS_CLEANACL_INVALID_ARG, MB_ICONERROR, IDS_CLEANACL_INVALID_ARG, names[i]);
760 ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONERROR, 0, names[i], GetAfsError(errno));
767 // Derived from fs.c's ListAclCmd
768 BOOL GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& strNegative)
771 register struct Acl *ta;
772 struct ViceIoctl blob;
774 int idf = 0; //getidf(as, parm_listacl_id);
778 blob.out_size = MAXSIZE;
780 blob.in = blob.out = space;
782 code = pioctl(PCCHAR(strDir), VIOCGETAL, &blob, 1);
784 ShowMessageBox(IDS_GETRIGHTS_ERROR, MB_ICONERROR, IDS_GETRIGHTS_ERROR, strDir, GetAfsError(errno));
788 ta = ParseAcl(space);
790 ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
794 ShowMessageBox(IDS_DFSACL_ERROR, MB_ICONERROR, IDS_DFSACL_ERROR);
799 // printf(" Default cell = %s\n", ta->cell);
804 for (te = ta->pluslist; te; te = te->next) {
805 strNormal.Add(te->name);
806 strNormal.Add(GetRightsString(te->rights, ta->dfs));
810 if (ta->nminus > 0) {
811 for (te = ta->minuslist; te; te = te->next) {
812 strNegative.Add(te->name);
813 strNegative.Add(GetRightsString(te->rights, ta->dfs));
820 struct AclEntry *FindList(register struct AclEntry *pCurEntry, const char *entryName)
823 if (!foldcmp(pCurEntry->name, PCCHAR(entryName)))
825 pCurEntry = pCurEntry->next;
831 void ChangeList (struct Acl *pAcl, BYTE bNormalRights, const char *entryName, LONG nEntryRights)
836 struct AclEntry *pEntry;
840 pEntry = (bNormalRights ? pAcl->pluslist : pAcl->minuslist);
841 pEntry = FindList(pEntry, entryName);
843 /* Found the item already in the list. */
845 pEntry->rights = nEntryRights;
847 pAcl->nplus -= PruneList(&pAcl->pluslist, pAcl->dfs);
849 pAcl->nminus -= PruneList(&pAcl->minuslist, pAcl->dfs);
853 /* Otherwise we make a new item and plug in the new data. */
854 pEntry = (struct AclEntry *) malloc(sizeof (struct AclEntry));
857 strcpy(pEntry->name, entryName);
858 pEntry->rights = nEntryRights;
861 pEntry->next = pAcl->pluslist;
862 pAcl->pluslist = pEntry;
864 if (nEntryRights == 0 || nEntryRights == -1)
865 pAcl->nplus -= PruneList(&pAcl->pluslist, pAcl->dfs);
868 pEntry->next = pAcl->minuslist;
869 pAcl->minuslist = pEntry;
871 if (nEntryRights == 0)
872 pAcl->nminus -= PruneList(&pAcl->minuslist, pAcl->dfs);
876 enum rtype {add, destroy, deny};
878 LONG Convert(const register char *arights, int dfs, enum rtype *rtypep)
884 *rtypep = add; /* add rights, by default */
886 if (!strcmp(arights,"read"))
887 return PRSFS_READ | PRSFS_LOOKUP;
888 if (!strcmp(arights, "write"))
889 return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
890 if (!strcmp(arights, "mail"))
891 return PRSFS_INSERT | PRSFS_LOCK | PRSFS_LOOKUP;
892 if (!strcmp(arights, "all"))
893 return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
895 if (!strcmp(arights, "none")) {
896 *rtypep = destroy; /* Remove entire entry */
900 len = strlen(arights);
903 for (i = 0; i < len; i++) {
905 if (tc == 'r') mode |= PRSFS_READ;
906 else if (tc == 'l') mode |= PRSFS_LOOKUP;
907 else if (tc == 'i') mode |= PRSFS_INSERT;
908 else if (tc == 'd') mode |= PRSFS_DELETE;
909 else if (tc == 'w') mode |= PRSFS_WRITE;
910 else if (tc == 'k') mode |= PRSFS_LOCK;
911 else if (tc == 'a') mode |= PRSFS_ADMINISTER;
913 fprintf(stderr, "illegal rights character '%c'.\n", tc);
920 BOOL SaveACL(const CString& strCellName, const CString& strDir, const CStringArray& normal, const CStringArray& negative)
923 struct ViceIoctl blob;
931 pAcl = EmptyAcl(strCellName);
933 // Set its normal rights
935 for (i = 0; i < normal.GetSize(); i += 2) {
936 rights = Convert(normal[i + 1], 0, &rtype);
937 ChangeList(pAcl, TRUE, normal[i], rights);
940 // Set its negative rights
941 for (i = 0; i < negative.GetSize(); i += 2) {
942 rights = Convert(negative[i + 1], 0, &rtype);
943 ChangeList(pAcl, FALSE, negative[i], rights);
947 blob.in = AclToString(pAcl);
949 blob.in_size = 1 + strlen((const char *)blob.in);
951 code = pioctl(PCCHAR(strDir), VIOCSETAL, &blob, 1);
954 ShowMessageBox(IDS_SAVE_ACL_EINVAL_ERROR, MB_ICONERROR, IDS_SAVE_ACL_EINVAL_ERROR, strDir);
956 ShowMessageBox(IDS_SAVE_ACL_ERROR, MB_ICONERROR, IDS_SAVE_ACL_ERROR, strDir, GetAfsError(errno, strDir));
964 BOOL CopyACL(const CString& strToDir, const CStringArray& normal, const CStringArray& negative, BOOL bClear)
967 struct ViceIoctl blob;
969 int idf = 0; // getidf(as, parm_copyacl_id);
973 // Get ACL to copy to
974 blob.out_size = MAXSIZE;
976 blob.in = blob.out = space;
978 code = pioctl(PCCHAR(strToDir), VIOCGETAL, &blob, 1);
980 ShowMessageBox(IDS_ACL_READ_ERROR, MB_ICONERROR, IDS_ACL_READ_ERROR, strToDir, GetAfsError(errno, strToDir));
985 pToAcl = EmptyAcl(space);
987 pToAcl = ParseAcl(space);
989 if (pToAcl == NULL) {
990 ShowMessageBox(IDS_INVALID_ACL_DATA, MB_ICONERROR, IDS_INVALID_ACL_DATA);
997 ShowMessageBox(IDS_NO_DFS_COPY_ACL, MB_ICONERROR, IDS_NO_DFS_COPY_ACL, strToDir);
1004 // Set normal rights
1006 for (i = 0; i < normal.GetSize(); i += 2) {
1007 LONG rights = Convert(normal[i + 1], 0, &rtype);
1008 ChangeList(pToAcl, TRUE, normal[i], rights);
1011 // Set negative rights
1012 for (i = 0; i < negative.GetSize(); i += 2) {
1013 LONG rights = Convert(negative[i + 1], 0, &rtype);
1014 ChangeList(pToAcl, FALSE, normal[i], rights);
1017 // Save modified ACL
1018 blob.in = AclToString(pToAcl);
1020 blob.in_size = 1 + strlen((char *)blob.in);
1022 code = pioctl(PCCHAR(strToDir), VIOCSETAL, &blob, 1);
1025 if (errno == EINVAL)
1026 ShowMessageBox(IDS_COPY_ACL_EINVAL_ERROR, MB_ICONERROR, IDS_COPY_ACL_EINVAL_ERROR, strToDir);
1028 ShowMessageBox(IDS_COPY_ACL_ERROR, MB_ICONERROR, IDS_COPY_ACL_ERROR, strToDir, GetAfsError(errno, strToDir));
1034 ShowMessageBox(IDS_COPY_ACL_OK, MB_OK|MB_ICONINFORMATION, IDS_COPY_ACL_OK);
1039 CString ParseMountPoint(const CString strFile, CString strMountPoint)
1044 CString strMountPointInfo;
1046 if (strMountPoint[0] == '#')
1047 strType = "Regular";
1048 else if (strMountPoint[0] == '%')
1049 strType = "Read/Write";
1051 int nColon = strMountPoint.Find(':');
1053 strCell = strMountPoint.Mid(1, nColon - 1);
1054 strVolume = strMountPoint.Mid(nColon + 1);
1056 strVolume = strMountPoint.Mid(1);
1058 strMountPointInfo = strFile + "\t" + strVolume + "\t" + strCell + "\t" + strType;
1060 return strMountPointInfo;
1063 CString ParseSymlink(const CString strFile, CString strSymlink)
1065 CString strSymlinkInfo;
1067 strSymlinkInfo = strFile + "\t" + strSymlink;
1069 return strSymlinkInfo;
1072 BOOL IsPathInAfs(const CHAR *strPath)
1074 struct ViceIoctl blob;
1077 HOURGLASS hourglass;
1080 sprintf(buf, "IsPathInAfs(%s)", strPath);
1081 OutputDebugString(buf);
1084 blob.out_size = MAXSIZE;
1087 code = pioctl((LPTSTR)((LPCTSTR)strPath), VIOC_FILE_CELL_NAME, &blob, 1);
1089 sprintf(buf, "VIOC_FILE_CELL_NAME=%d", code);
1090 OutputDebugString(buf);
1093 if ((errno == EINVAL) || (errno == ENOENT))
1100 IsFreelanceRoot(char *apath)
1102 struct ViceIoctl blob;
1106 blob.out_size = MAXSIZE;
1109 code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
1111 return !strcmp("Freelance.Local.Root",space);
1112 return 1; /* assume it is because it is more restrictive that way */
1115 const char * NetbiosName(void)
1117 static char buffer[1024] = "AFS";
1123 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
1124 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey);
1125 if (code == ERROR_SUCCESS) {
1126 dummyLen = sizeof(buffer);
1127 code = RegQueryValueEx(parmKey, "NetbiosName", NULL, NULL,
1128 (LPBYTE)buffer, &dummyLen);
1129 RegCloseKey (parmKey);
1131 strcpy(buffer, "AFS");
1136 #define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins"
1138 static BOOL IsAdmin (void)
1140 static BOOL fAdmin = FALSE;
1141 static BOOL fTested = FALSE;
1145 /* Obtain the SID for the AFS client admin group. If the group does
1146 * not exist, then assume we have AFS client admin privileges.
1148 PSID psidAdmin = NULL;
1149 DWORD dwSize, dwSize2;
1150 char pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ];
1151 char *pszRefDomain = NULL;
1152 SID_NAME_USE snu = SidTypeGroup;
1154 dwSize = sizeof(pszAdminGroup);
1156 if (!GetComputerName(pszAdminGroup, &dwSize)) {
1157 /* Can't get computer name. We return false in this case.
1158 Retain fAdmin and fTested. This shouldn't happen.*/
1165 strcat(pszAdminGroup,"\\");
1166 strcat(pszAdminGroup, AFSCLIENT_ADMIN_GROUPNAME);
1168 LookupAccountName(NULL, pszAdminGroup, NULL, &dwSize, NULL, &dwSize2, &snu);
1169 /* that should always fail. */
1171 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
1172 /* if we can't find the group, then we allow the operation */
1177 if (dwSize == 0 || dwSize2 == 0) {
1183 psidAdmin = (PSID)malloc(dwSize); memset(psidAdmin,0,dwSize);
1184 pszRefDomain = (char *)malloc(dwSize2);
1186 if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) {
1187 /* We can't lookup the group now even though we looked it up earlier.
1188 Could this happen? */
1191 /* Then open our current ProcessToken */
1194 if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken))
1197 if (!CheckTokenMembership(hToken, psidAdmin, &fAdmin)) {
1198 /* We'll have to allocate a chunk of memory to store the list of
1199 * groups to which this user belongs; find out how much memory
1203 PTOKEN_GROUPS pGroups;
1205 GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize);
1207 pGroups = (PTOKEN_GROUPS)malloc(dwSize);
1209 /* Allocate that buffer, and read in the list of groups. */
1210 if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize))
1212 /* Look through the list of group SIDs and see if any of them
1213 * matches the AFS Client Admin group SID.
1216 for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup)
1218 if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) {
1228 /* if do not have permission because we were not explicitly listed
1229 * in the Admin Client Group let's see if we are the SYSTEM account
1232 PTOKEN_USER pTokenUser;
1233 SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
1234 PSID pSidLocalSystem = 0;
1237 GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
1239 pTokenUser = (PTOKEN_USER)malloc(dwSize);
1241 if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize))
1242 gle = GetLastError();
1244 if (AllocateAndInitializeSid( &SIDAuth, 1,
1245 SECURITY_LOCAL_SYSTEM_RID,
1246 0, 0, 0, 0, 0, 0, 0,
1249 if (EqualSid(pTokenUser->User.Sid, pSidLocalSystem)) {
1253 FreeSid(pSidLocalSystem);
1271 /* return a static pointer to a buffer */
1272 static char *Parent(char *apath)
1276 strcpy(tspace, apath);
1277 tp = strrchr(tspace, '\\');
1279 *(tp+1) = 0; /* lv trailing slash so Parent("k:\foo") is "k:\" not "k:" */
1282 fs_ExtractDriveLetter(apath, tspace);
1283 strcat(tspace, ".");
1290 GetCell(char *fname, char *cellname)
1293 struct ViceIoctl blob;
1296 blob.out_size = MAXCELLCHARS;
1297 blob.out = cellname;
1299 code = pioctl(fname, VIOC_FILE_CELL_NAME, &blob, 1);
1300 return code ? errno : 0;
1304 BOOL ListMount(CStringArray& files)
1307 struct ViceIoctl blob;
1309 char orig_name[1024]; /* Original name, may be modified */
1310 char true_name[1024]; /* ``True'' dirname (e.g., symlink target) */
1311 char parent_dir[1024]; /* Parent directory of true name */
1312 register char *last_component; /* Last component of true name */
1313 CStringArray mountPoints;
1315 HOURGLASS hourglass;
1319 for (int i = 0; i < files.GetSize(); i++) {
1320 strcpy(orig_name, files[i]);
1321 strcpy(true_name, orig_name);
1324 * Find rightmost slash, if any.
1326 last_component = (char *)strrchr(true_name, '\\');
1327 if (last_component) {
1329 * Found it. Designate everything before it as the parent directory,
1330 * everything after it as the final component.
1332 strncpy(parent_dir, true_name, last_component - true_name + 1);
1333 parent_dir[last_component - true_name + 1] = 0;
1334 last_component++; /* Skip the slash */
1336 if (!IsPathInAfs(parent_dir)) {
1337 const char * nbname = NetbiosName();
1338 int len = strlen(nbname);
1340 if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
1341 parent_dir[len+2] == '\\' &&
1342 parent_dir[len+3] == '\0' &&
1343 !strnicmp(nbname,&parent_dir[2],len))
1345 sprintf(parent_dir,"\\\\%s\\all\\", nbname);
1351 * No slash appears in the given file name. Set parent_dir to the current
1352 * directory, and the last component as the given name.
1354 fs_ExtractDriveLetter(true_name, parent_dir);
1355 strcat(parent_dir, ".");
1356 last_component = true_name;
1357 fs_StripDriveLetter(true_name, true_name, sizeof(true_name));
1360 blob.in = last_component;
1361 blob.in_size = strlen(last_component) + 1;
1362 blob.out_size = MAXSIZE;
1364 memset(space, 0, MAXSIZE);
1366 code = pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
1368 int nPos = strlen(space) - 1;
1369 if (space[nPos] == '.')
1371 mountPoints.Add(ParseMountPoint(StripPath(files[i]), space));
1374 if (errno == EINVAL)
1375 mountPoints.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(files[i])));
1377 mountPoints.Add(GetMessageString(IDS_LIST_MOUNT_POINT_ERROR, GetAfsError(errno, StripPath(files[i]))));
1381 CMountPointsDlg dlg;
1382 dlg.SetMountPoints(mountPoints);
1388 BOOL MakeMount(const CString& strDir, const CString& strVolName, const CString& strCellName, BOOL bRW)
1391 register char *cellName;
1392 char localCellName[128];
1393 struct afsconf_cell info;
1395 struct vldbentry vldbEntry;
1397 struct ViceIoctl blob;
1399 char path[1024] = "";
1401 HOURGLASS hourglass;
1403 ASSERT(strVolName.GetLength() < 64);
1405 if (strCellName.GetLength() > 0) /* cell name specified */
1406 cellName = PCCHAR(strCellName);
1408 cellName = (char *) 0;
1410 parent = Parent(PCCHAR(strDir));
1411 if (!IsPathInAfs(parent)) {
1412 const char * nbname = NetbiosName();
1413 int len = strlen(nbname);
1415 if (parent[0] == '\\' && parent[1] == '\\' &&
1416 parent[len+2] == '\\' &&
1417 parent[len+3] == '\0' &&
1418 !strnicmp(nbname,&parent[2],len))
1420 sprintf(path,"%sall\\%s", parent, &(PCCHAR(strDir)[strlen(parent)]));
1421 parent = Parent(path);
1422 if (!IsPathInAfs(parent)) {
1423 ShowMessageBox(IDS_MAKE_MP_NOT_AFS_ERROR, MB_ICONERROR, IDS_MAKE_MP_NOT_AFS_ERROR);
1427 ShowMessageBox(IDS_MAKE_MP_NOT_AFS_ERROR, MB_ICONERROR, IDS_MAKE_MP_NOT_AFS_ERROR);
1432 if ( strlen(path) == 0 )
1433 strcpy(path, PCCHAR(strDir));
1435 if ( IsFreelanceRoot(parent) ) {
1437 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
1443 blob.out_size = sizeof(localCellName);
1444 blob.out = localCellName;
1445 code = pioctl(parent, VIOC_GET_WS_CELL, &blob, 1);
1447 cellName = localCellName;
1451 GetCell(parent,space);
1454 code = GetCellName(cellName?cellName:space, &info);
1460 code = VLDBInit(1, &info);
1462 /* make the check. Don't complain if there are problems with init */
1463 code = ubik_VL_GetEntryByNameO(uclient, 0, PCCHAR(strVolName), &vldbEntry);
1464 if (code == VL_NOENT) {
1465 ShowMessageBox(IDS_WARNING, MB_ICONWARNING, IDS_VOLUME_NOT_IN_CELL_WARNING,
1466 PCCHAR(strVolName), cellName ? cellName : space);
1473 if (bRW) /* if -rw specified */
1478 /* If cellular mount point, prepend cell prefix */
1480 strcat(space, info.name);
1484 strcat(space, strVolName); /* append volume name */
1485 strcat(space, "."); /* stupid convention; these end with a period */
1487 /* create symlink with a special pioctl for Windows NT, since it doesn't
1488 * have a symlink system call.
1491 blob.in_size = 1 + strlen(space);
1494 code = pioctl(path, VIOC_AFS_CREATE_MT_PT, &blob, 0);
1497 ShowMessageBox(IDS_MOUNT_POINT_ERROR, MB_ICONERROR, IDS_MOUNT_POINT_ERROR, GetAfsError(errno, strDir));
1506 long fs_ExtractDriveLetter(const char *inPathp, char *outPathp)
1508 if (inPathp[0] != 0 && inPathp[1] == ':') {
1509 /* there is a drive letter */
1510 *outPathp++ = *inPathp++;
1511 *outPathp++ = *inPathp++;
1519 /* strip the drive letter from a component */
1520 long fs_StripDriveLetter(const char *inPathp, char *outPathp, long outSize)
1522 char tempBuffer[1000];
1523 strcpy(tempBuffer, inPathp);
1524 if (tempBuffer[0] != 0 && tempBuffer[1] == ':') {
1525 /* drive letter present */
1526 strcpy(outPathp, tempBuffer+2);
1529 /* no drive letter present */
1530 strcpy(outPathp, tempBuffer);
1536 BOOL RemoveSymlink(const char * linkName)
1540 struct ViceIoctl blob;
1542 char lsbuffer[1024];
1543 char tpbuffer[1024];
1546 HOURGLASS hourglass;
1548 tp = (char *) strrchr(linkName, '\\');
1550 tp = (char *) strrchr(linkName, '/');
1552 strncpy(tbuffer, linkName, code=tp-linkName+1); /* the dir name */
1554 tp++; /* skip the slash */
1556 if (!IsPathInAfs(tbuffer)) {
1557 const char * nbname = NetbiosName();
1558 int len = strlen(nbname);
1560 if (tbuffer[0] == '\\' && tbuffer[1] == '\\' &&
1561 tbuffer[len+2] == '\\' &&
1562 tbuffer[len+3] == '\0' &&
1563 !strnicmp(nbname,&tbuffer[2],len))
1565 sprintf(tbuffer,"\\\\%s\\all\\", nbname);
1570 fs_ExtractDriveLetter(linkName, tbuffer);
1571 strcat(tbuffer, ".");
1572 fs_StripDriveLetter(tp, tpbuffer, 0);
1576 if ( IsFreelanceRoot(tbuffer) && !IsAdmin() ) {
1577 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
1582 blob.in_size = strlen(tp)+1;
1583 blob.out = lsbuffer;
1584 blob.out_size = sizeof(lsbuffer);
1585 code = pioctl(tbuffer, VIOC_LISTSYMLINK, &blob, 0);
1590 blob.in_size = strlen(tp)+1;
1591 return (pioctl(tbuffer, VIOC_DELSYMLINK, &blob, 0)==0);
1594 BOOL IsSymlink(const char * true_name)
1596 char parent_dir[MAXSIZE]; /*Parent directory of true name*/
1597 char strip_name[MAXSIZE];
1598 struct ViceIoctl blob;
1599 char *last_component;
1602 HOURGLASS hourglass;
1605 sprintf(buf, "IsSymlink(%s)", true_name);
1606 OutputDebugString(buf);
1608 last_component = (char *) strrchr(true_name, '\\');
1609 if (!last_component)
1610 last_component = (char *) strrchr(true_name, '/');
1611 if (last_component) {
1613 * Found it. Designate everything before it as the parent directory,
1614 * everything after it as the final component.
1616 strncpy(parent_dir, true_name, last_component - true_name + 1);
1617 parent_dir[last_component - true_name + 1] = 0;
1618 last_component++; /*Skip the slash*/
1620 if (!IsPathInAfs(parent_dir)) {
1621 const char * nbname = NetbiosName();
1622 int len = strlen(nbname);
1624 if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
1625 parent_dir[len+2] == '\\' &&
1626 parent_dir[len+3] == '\0' &&
1627 !strnicmp(nbname,&parent_dir[2],len))
1629 sprintf(parent_dir,"\\\\%s\\all\\", nbname);
1635 * No slash appears in the given file name. Set parent_dir to the current
1636 * directory, and the last component as the given name.
1638 fs_ExtractDriveLetter(true_name, parent_dir);
1639 strcat(parent_dir, ".");
1640 last_component = strip_name;
1641 fs_StripDriveLetter(true_name, strip_name, sizeof(strip_name));
1644 sprintf(buf, "last_component=%s", last_component);
1645 OutputDebugString(buf);
1647 blob.in = last_component;
1648 blob.in_size = strlen(last_component)+1;
1649 blob.out_size = MAXSIZE;
1651 memset(space, 0, MAXSIZE);
1652 code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1);
1657 BOOL IsMountPoint(const char * name)
1659 register LONG code = 0;
1660 struct ViceIoctl blob;
1662 char lsbuffer[1024];
1664 char szCurItem[1024];
1666 HOURGLASS hourglass;
1668 strcpy(szCurItem, name);
1671 sprintf(buf, "IsMountPoint(%s)", name);
1672 OutputDebugString(buf);
1674 tp = (char *)strrchr(szCurItem, '\\');
1676 strncpy(tbuffer, szCurItem, code = tp - szCurItem + 1); /* the dir name */
1678 tp++; /* skip the slash */
1680 if (!IsPathInAfs(tbuffer)) {
1681 const char * nbname = NetbiosName();
1682 int len = strlen(nbname);
1684 if (tbuffer[0] == '\\' && tbuffer[1] == '\\' &&
1685 tbuffer[len+2] == '\\' &&
1686 tbuffer[len+3] == '\0' &&
1687 !strnicmp(nbname,&tbuffer[2],len))
1689 sprintf(tbuffer,"\\\\%s\\all\\", nbname);
1693 fs_ExtractDriveLetter(szCurItem, tbuffer);
1694 strcat(tbuffer, ".");
1696 fs_StripDriveLetter(tp, tp, 0);
1699 sprintf(buf, "last_component=%s", tp);
1700 OutputDebugString(buf);
1703 blob.in_size = strlen(tp)+1;
1704 blob.out = lsbuffer;
1705 blob.out_size = sizeof(lsbuffer);
1707 code = pioctl(tbuffer, VIOC_AFS_STAT_MT_PT, &blob, 0);
1714 * Delete AFS mount points. Variables are used as follows:
1715 * tbuffer: Set to point to the null-terminated directory name of the mount point
1716 * (or ``.'' if none is provided)
1717 * tp: Set to point to the actual name of the mount point to nuke.
1719 BOOL RemoveMount(CStringArray& files)
1721 register LONG code = 0;
1722 struct ViceIoctl blob;
1725 char szCurItem[1024];
1727 CStringArray results;
1731 HOURGLASS hourglass;
1733 for (int i = 0; i < files.GetSize(); i++) {
1734 if (!IsMountPoint(files[i])) {
1736 if (errno == EINVAL)
1737 results.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(files[i])));
1739 results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
1740 continue; // don't bother trying
1743 strcpy(szCurItem, files[i]);
1745 tp = (char *)strrchr(szCurItem, '\\');
1747 strncpy(tbuffer, szCurItem, code = tp - szCurItem + 1); /* the dir name */
1749 tp++; /* skip the slash */
1751 if (!IsPathInAfs(tbuffer)) {
1752 const char * nbname = NetbiosName();
1753 int len = strlen(nbname);
1755 if (tbuffer[0] == '\\' && tbuffer[1] == '\\' &&
1756 tbuffer[len+2] == '\\' &&
1757 tbuffer[len+3] == '\0' &&
1758 !strnicmp(nbname,&tbuffer[2],len))
1760 sprintf(tbuffer,"\\\\%s\\all\\", nbname);
1764 fs_ExtractDriveLetter(szCurItem, tbuffer);
1765 strcat(tbuffer, ".");
1767 fs_StripDriveLetter(tp, tp, 0);
1770 if ( IsFreelanceRoot(tbuffer) && !IsAdmin() ) {
1771 results.Add(GetMessageString(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, StripPath(files[i])));
1773 continue; /* skip */
1778 blob.in_size = strlen(tp)+1;
1780 code = pioctl(tbuffer, VIOC_AFS_DELETE_MT_PT, &blob, 0);
1783 results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
1785 results.Add(GetMessageString(IDS_DELETED));
1788 LoadString (str, IDS_REMOVE_MP);
1789 LoadString (str2, IDS_REMOVE_MP_COLUMN);
1790 CResultsDlg dlg(REMOVE_MOUNT_POINTS_HELP_ID);
1791 dlg.SetContents(str, str2, StripPath(files), results);
1797 BOOL GetVolumeInfo(CString strFile, CVolInfo& volInfo)
1800 struct ViceIoctl blob;
1801 struct VolumeStatus *status;
1804 HOURGLASS hourglass;
1806 volInfo.m_strFilePath = strFile;
1807 volInfo.m_strFileName = StripPath(strFile);
1810 volInfo.m_strName = "VolumeName";
1812 volInfo.m_nQuota = 20 * 1024 * 1024;
1813 volInfo.m_nNewQuota = volInfo.m_nQuota;
1814 volInfo.m_nUsed = volInfo.m_nQuota / 2;
1815 volInfo.m_nPartSize = 50 * 1024 * 1024;
1816 volInfo.m_nPartFree = 30 * 1024 * 1024;
1817 volInfo.m_nDup = -1;
1821 blob.out_size = MAXSIZE;
1825 code = pioctl(PCCHAR(strFile), VIOCGETVOLSTAT, &blob, 1);
1827 volInfo.m_strErrorMsg = GetAfsError(errno, strFile);
1831 status = (VolumeStatus *)space;
1832 name = (char *)status + sizeof(*status);
1834 volInfo.m_strName = name;
1835 volInfo.m_nID = status->Vid;
1836 volInfo.m_nQuota = status->MaxQuota;
1837 volInfo.m_nNewQuota = status->MaxQuota;
1838 volInfo.m_nUsed = status->BlocksInUse;
1839 volInfo.m_nPartSize = status->PartMaxBlocks;
1840 volInfo.m_nPartFree = status->PartBlocksAvail;
1841 volInfo.m_nDup = -1;
1846 BOOL SetVolInfo(CVolInfo& volInfo)
1849 struct ViceIoctl blob;
1850 struct VolumeStatus *status;
1853 HOURGLASS hourglass;
1855 blob.out_size = MAXSIZE;
1856 blob.in_size = sizeof(*status) + 3; /* for the three terminating nulls */
1860 status = (VolumeStatus *)space;
1861 status->MinQuota = -1;
1862 status->MaxQuota = volInfo.m_nNewQuota;
1864 input = (char *)status + sizeof(*status);
1865 *(input++) = '\0'; /* never set name: this call doesn't change vldb */
1866 *(input++) = '\0'; // No offmsg
1867 *(input++) = '\0'; // No motd
1870 FILE *fp = OpenFile(szLogFileName, "a");
1872 fprintf(fp, "\nSetVolInfo() pioctl parms:\n");
1873 fprintf(fp, "\tpathp = %s\n\topcode = VIOCSETVOLSTAT (%d)\n\tblobp = %ld\n", PCCHAR(volInfo.m_strFilePath), VIOCSETVOLSTAT, &blob);
1874 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);
1875 fprintf(fp, "\t\t\tstatus->MinQuota = %ld\n", status->MinQuota);
1876 fprintf(fp, "\t\t\tstatus->MaxQuota = %ld\n", status->MaxQuota);
1877 fprintf(fp, "\t\t\tOther status fields aren't set\n");
1878 fprintf(fp, "\t\t\t3 nulls follow the VolumeStatus structure.\n");
1879 fprintf(fp, "\tfollow = 1\n");
1884 code = pioctl(PCCHAR(volInfo.m_strFilePath), VIOCSETVOLSTAT, &blob, 1);
1886 ShowMessageBox(IDS_SET_QUOTA_ERROR, MB_ICONERROR, IDS_SET_QUOTA_ERROR, GetAfsError(errno, volInfo.m_strName));
1893 int GetCellName(char *cellNamep, struct afsconf_cell *infop)
1895 strcpy(infop->name, cellNamep);
1899 BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast)
1902 struct ViceIoctl blob;
1905 struct afsconf_cell info;
1906 struct chservinfo checkserv;
1908 HOURGLASS hourglass;
1910 memset(&checkserv, 0, sizeof(struct chservinfo));
1911 blob.in_size = sizeof(struct chservinfo);
1912 blob.in = (caddr_t)&checkserv;
1914 blob.out_size = MAXSIZE;
1916 memset(space, 0, sizeof(afs_int32)); /* so we assure zero when nothing is copied back */
1918 if (nCellsToCheck == SPECIFIC_CELL) {
1920 GetCellName(PCCHAR(strCellName), &info);
1921 strcpy(checkserv.tbuffer,info.name);
1922 checkserv.tsize = strlen(info.name) + 1;
1924 if (nCellsToCheck != ALL_CELLS)
1926 strcpy(checkserv.tbuffer, "\0");
1927 checkserv.tsize = 0;
1930 temp |= 1; /* set fast flag */
1932 checkserv.magic = 0x12345678; /* XXX */
1933 checkserv.tflags = temp;
1934 checkserv.tinterval = -1; /* don't change current interval */
1936 code = pioctl(0, VIOCCKSERV, &blob, 1);
1938 ShowMessageBox(IDS_CHECK_SERVERS_ERROR, MB_ICONERROR, IDS_CHECK_SERVERS_ERROR, GetAfsError(errno, CString()));
1942 memcpy(&temp, space, sizeof(LONG));
1945 ShowMessageBox(IDS_ALL_SERVERS_RUNNING, MB_OK|MB_ICONINFORMATION, IDS_ALL_SERVERS_RUNNING);
1949 CStringArray servers;
1950 for (j = 0; j < MAXHOSTS; j++) {
1951 memcpy(&temp, space + j * sizeof(LONG), sizeof(LONG));
1955 char *name = hostutil_GetNameByINet(temp);
1959 CDownServersDlg dlg;
1960 dlg.SetServerNames(servers);
1966 BOOL GetTokenInfo(CStringArray& tokenInfo)
1970 time_t current_time;
1971 time_t tokenExpireTime;
1975 struct ktc_principal serviceName, clientName;
1976 struct ktc_token token;
1978 CString strTokenInfo;
1979 CString strUserName;
1980 CString strCellName;
1983 // tokenInfo.Add("");
1987 HOURGLASS hourglass;
1989 // printf("\nTokens held by the Cache Manager:\n\n");
1991 current_time = time(0);
1994 rc = ktc_ListTokens(cellNum, &cellNum, &serviceName);
1995 if (rc == KTC_NOENT) {
1997 // printf(" --End of list --\n");
2000 else if (rc == KTC_NOCM) {
2001 ShowMessageBox(IDS_GET_TOKENS_NO_AFS_SERVICE);
2002 // printf("AFS service may not have started\n");
2006 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR, MB_ICONERROR, IDS_GET_TOKENS_UNEXPECTED_ERROR, rc);
2008 // printf("Unexpected error, code %d\n", rc);
2012 rc = ktc_GetToken(&serviceName, &token, sizeof(token), &clientName);
2014 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR2, MB_ICONERROR, IDS_GET_TOKENS_UNEXPECTED_ERROR2,
2015 serviceName.name, serviceName.instance, serviceName.cell, rc);
2019 tokenExpireTime = token.endTime;
2021 strcpy(userName, clientName.name);
2022 if (clientName.instance[0] != 0) {
2023 strcat(userName, ".");
2024 strcat(userName, clientName.instance);
2027 BOOL bShowName = FALSE;
2029 if (userName[0] == '\0')
2030 ; //printf("Tokens");
2031 // AFS ID is not returned at this time.
2032 // else if (strncmp(userName, "AFS ID", 6) == 0)
2033 // printf("User's (%s) tokens", userName);
2034 // sscanf(userName, "(AFS ID %s)", szAfsID);
2035 else if (strncmp(userName, "Unix UID", 8) == 0)
2036 ; //printf("Tokens");
2038 strUserName = userName;
2039 // printf("User %s's tokens", userName);
2041 // printf(" for %s%s%s@%s ", serviceName.name, serviceName.instance[0] ? "." : "", serviceName.instance, serviceName.cell);
2042 strCellName = serviceName.cell;
2044 if (tokenExpireTime <= current_time)
2045 strExpir = "[>> Expired <<]";
2046 // printf("[>> Expired <<]\n");
2048 expireString = ctime(&tokenExpireTime);
2049 expireString += 4; /* Skip day of week */
2050 expireString[12] = '\0'; /* Omit secs & year */
2051 // printf("[Expires %s]\n", expireString);
2052 strExpir.Format("%s", expireString);
2055 strTokenInfo = strUserName + "\t" + strCellName + "\t" + strExpir + "\t" + strCellName;
2056 tokenInfo.Add(strTokenInfo);
2060 // printf("Press <Enter> or <Return> when finished: ");
2065 UINT MakeSymbolicLink(const char *strName, const char *strTarget)
2067 struct ViceIoctl blob;
2068 char space[MAXSIZE];
2070 char path[1024] = "";
2073 HOURGLASS hourglass;
2074 static char message[2048];
2076 strcpy(path, strName);
2077 parent = Parent(path);
2079 sprintf(message,"MakeSymbolicLink: name = %s target = %s parent = %s\n",strName,strTarget, parent);
2080 OutputDebugString(message);
2082 if ( IsFreelanceRoot(parent) && !IsAdmin() ) {
2083 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
2087 LPTSTR lpsz = new TCHAR[strlen(strTarget)+1];
2088 _tcscpy(lpsz, strName);
2089 strcpy(space, strTarget);
2091 blob.in_size = 1 + strlen(space);
2094 code=pioctl(lpsz, VIOC_SYMLINK, &blob, 0);
2101 void ListSymbolicLinkPath(const char *strName,char *strPath,UINT nlenPath)
2103 ASSERT(nlenPath<MAX_PATH);
2104 struct ViceIoctl blob;
2105 char orig_name[MAX_PATH+1]; /*Original name, may be modified*/
2106 char true_name[MAX_PATH+1]; /*``True'' dirname (e.g., symlink target)*/
2107 char parent_dir[MAX_PATH+1]; /*Parent directory of true name*/
2108 char *last_component; /*Last component of true name*/
2111 HOURGLASS hourglass;
2113 strcpy(orig_name, strName);
2114 strcpy(true_name, orig_name);
2116 * Find rightmost slash, if any.
2118 last_component = (char *) strrchr(true_name, '\\');
2119 if (!last_component)
2120 last_component = (char *) strrchr(true_name, '/');
2121 if (last_component) {
2123 * Found it. Designate everything before it as the parent directory,
2124 * everything after it as the final component.
2126 strncpy(parent_dir, true_name, last_component - true_name + 1);
2127 parent_dir[last_component - true_name + 1] = 0;
2128 last_component++; /*Skip the slash*/
2130 if (!IsPathInAfs(parent_dir)) {
2131 const char * nbname = NetbiosName();
2132 int len = strlen(nbname);
2134 if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
2135 parent_dir[len+2] == '\\' &&
2136 parent_dir[len+3] == '\0' &&
2137 !strnicmp(nbname,&parent_dir[2],len))
2139 sprintf(parent_dir,"\\\\%s\\all\\", nbname);
2145 * No slash appears in the given file name. Set parent_dir to the current
2146 * directory, and the last component as the given name.
2148 fs_ExtractDriveLetter(true_name, parent_dir);
2149 strcat(parent_dir, ".");
2150 last_component = true_name;
2151 fs_StripDriveLetter(true_name, true_name, sizeof(true_name));
2153 blob.in = last_component;
2154 blob.in_size = strlen(last_component)+1;
2155 blob.out_size = MAXSIZE;
2157 memset(space, 0, MAXSIZE);
2158 if ((code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1)))
2159 strcpy(space,"???");
2160 ASSERT(strlen(space)<MAX_PATH);
2161 strncpy(strPath,space,nlenPath);
2164 BOOL ListSymlink(CStringArray& files)
2167 struct ViceIoctl blob;
2169 char orig_name[1024]; /* Original name, may be modified */
2170 char true_name[1024]; /* ``True'' dirname (e.g., symlink target) */
2171 char parent_dir[1024]; /* Parent directory of true name */
2172 register char *last_component; /* Last component of true name */
2173 CStringArray symlinks;
2175 HOURGLASS hourglass;
2179 for (int i = 0; i < files.GetSize(); i++) {
2180 strcpy(orig_name, files[i]);
2181 strcpy(true_name, orig_name);
2184 * Find rightmost slash, if any.
2186 last_component = (char *)strrchr(true_name, '\\');
2187 if (last_component) {
2189 * Found it. Designate everything before it as the parent directory,
2190 * everything after it as the final component.
2192 strncpy(parent_dir, true_name, last_component - true_name + 1);
2193 parent_dir[last_component - true_name + 1] = 0;
2194 last_component++; /* Skip the slash */
2196 if (!IsPathInAfs(parent_dir)) {
2197 const char * nbname = NetbiosName();
2198 int len = strlen(nbname);
2200 if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
2201 parent_dir[len+2] == '\\' &&
2202 parent_dir[len+3] == '\0' &&
2203 !strnicmp(nbname,&parent_dir[2],len))
2205 sprintf(parent_dir,"\\\\%s\\all\\", nbname);
2211 * No slash appears in the given file name. Set parent_dir to the current
2212 * directory, and the last component as the given name.
2214 fs_ExtractDriveLetter(true_name, parent_dir);
2215 strcat(parent_dir, ".");
2216 last_component = true_name;
2217 fs_StripDriveLetter(true_name, true_name, sizeof(true_name));
2220 blob.in = last_component;
2221 blob.in_size = strlen(last_component) + 1;
2222 blob.out_size = MAXSIZE;
2224 memset(space, 0, MAXSIZE);
2226 code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1);
2228 int nPos = strlen(space) - 1;
2229 if (space[nPos] == '.')
2231 symlinks.Add(ParseSymlink(StripPath(files[i]), space));
2234 if (errno == EINVAL)
2235 symlinks.Add(GetMessageString(IDS_NOT_SYMLINK_ERROR, StripPath(files[i])));
2237 symlinks.Add(GetMessageString(IDS_LIST_MOUNT_POINT_ERROR, GetAfsError(errno, StripPath(files[i]))));
2242 dlg.SetSymlinks(symlinks);