2 * Copyright (C) 1997 Transarc Corporation.
18 #include "results_dlg.h"
19 #include "volume_inf.h"
20 #include "mount_points_dlg.h"
21 #include "hourglass.h"
22 #include "down_servers_dlg.h"
25 #include <afs/param.h>
34 #define PCCHAR(str) ((char *)(const char *)(str))
41 #define MAXINSIZE 1300 /* pioctl complains if data is larger than this */
42 #define VMSGSIZE 128 /* size of msg buf in volume hdr */
44 #define MAXCELLCHARS 64
45 #define MAXHOSTCHARS 64
46 #define MAXHOSTSPERCELL 8
49 char name[MAXCELLCHARS];
52 struct sockaddr_in hostAddr[MAXHOSTSPERCELL];
53 char hostName[MAXHOSTSPERCELL][MAXHOSTCHARS];
57 static char space[MAXSIZE];
58 static char tspace[1024];
60 // #define LOGGING_ON // Enable this to log certain pioctl calls
63 static char *szLogFileName = "afsguilog.txt";
67 FILE *OpenFile(char *file, char *rwp)
74 code = GetWindowsDirectory(wdir, sizeof(wdir));
75 if (code == 0 || code > sizeof(wdir))
78 /* add trailing backslash, if required */
80 if (wdir[tlen - 1] != '\\')
85 fp = fopen(wdir, rwp);
90 CString StripPath(CString& strPath)
92 int nIndex = strPath.ReverseFind('\\');
94 CString strFile = strPath.Mid(nIndex + 1);
95 if (strFile.IsEmpty())
101 CStringArray& StripPath(CStringArray& files)
103 for (int i = 0; i < files.GetSize(); i++)
104 files[i] = StripPath(files[i]);
109 void Flush(const CStringArray& files)
112 struct ViceIoctl blob;
117 for (int i = 0; i < files.GetSize(); i++) {
118 blob.in_size = blob.out_size = 0;
120 code = pioctl(PCCHAR(files[i]), VIOCFLUSH, &blob, 0);
124 ShowMessageBox(IDS_FLUSH_FAILED, MB_ICONEXCLAMATION, IDS_FLUSH_FAILED, files[i]);
126 ShowMessageBox(IDS_FLUSH_ERROR, MB_ICONEXCLAMATION, IDS_FLUSH_ERROR, files[i], strerror(errno));
131 ShowMessageBox(IDS_FLUSH_OK, MB_ICONEXCLAMATION, IDS_FLUSH_OK);
134 void FlushVolume(const CStringArray& files)
137 struct ViceIoctl blob;
142 for (int i = 0; i < files.GetSize(); i++) {
143 blob.in_size = blob.out_size = 0;
145 code = pioctl(PCCHAR(files[i]), VIOC_FLUSHVOLUME, &blob, 0);
148 ShowMessageBox(IDS_FLUSH_VOLUME_ERROR, MB_ICONEXCLAMATION, IDS_FLUSH_VOLUME_ERROR, files[i], strerror(errno));
153 ShowMessageBox(IDS_FLUSH_VOLUME_OK, MB_ICONEXCLAMATION, IDS_FLUSH_VOLUME_OK);
156 void WhichCell(CStringArray& files)
159 struct ViceIoctl blob;
164 CStringArray results;
170 for (int i = 0; i < files.GetSize(); i++) {
172 blob.out_size = MAXSIZE;
175 code = pioctl(PCCHAR(files[i]), VIOC_FILE_CELL_NAME, &blob, 1);
177 if (code == ENOENT) {
178 LoadString (str, IDS_CANT_GET_CELL);
181 results.Add(GetAfsError(errno));
186 LoadString (str, IDS_SHOW_CELL);
187 LoadString (str2, IDS_SHOW_CELL_COLUMN);
188 CResultsDlg dlg(SHOW_CELL_HELP_ID);
189 dlg.SetContents(str, str2, StripPath(files), results);
196 struct ViceIoctl blob;
201 blob.in = (char *) 0;
202 blob.out_size = MAXSIZE;
205 code = pioctl((char *) 0, VIOC_GET_WS_CELL, &blob, 1);
208 //Die(errno, (char *) 0);
211 //printf("This workstation belongs to cell '%s'\n", space);
217 struct ViceIoctl blob;
221 code = pioctl(0, VIOCCKBACK, &blob, 1);
223 ShowMessageBox(IDS_CHECK_VOLUMES_ERROR, MB_ICONEXCLAMATION, IDS_CHECK_VOLUMES_ERROR, GetAfsError(errno, CString()));
227 ShowMessageBox(IDS_CHECK_VOLUMES_OK, MB_OK, IDS_CHECK_VOLUMES_OK);
232 void SetCacheSizeCmd(LONG nNewCacheSize)
235 struct ViceIoctl blob;
239 blob.in = (char *) &nNewCacheSize;
240 blob.in_size = sizeof(LONG);
243 code = pioctl(0, VIOCSETCACHESIZE, &blob, 1);
245 // Die(errno, (char *) 0);
247 // printf("New cache size set.\n");
250 void WhereIs(CStringArray& files)
253 struct ViceIoctl blob;
254 CStringArray servers;
255 CStringArray resultFiles;
261 for (int i = 0; i < files.GetSize(); i++) {
262 blob.out_size = MAXSIZE;
265 memset(space, 0, sizeof(space));
267 code = pioctl(PCCHAR(files[i]), VIOCWHEREIS, &blob, 1);
269 resultFiles.Add(StripPath(files[i]));
270 servers.Add(GetAfsError(errno));
274 LONG *hosts = (LONG *)space;
278 for (int j = 0; j < MAXHOSTS; j++) {
281 char *hostName = hostutil_GetNameByINet(hosts[j]);
283 resultFiles.Add(StripPath(files[i]));
286 resultFiles.Add(" ");
287 servers.Add(hostName);
291 LoadString (str, IDS_SHOW_FS);
292 LoadString (str2, IDS_SHOW_FS_COLUMN);
293 CResultsDlg dlg(SHOW_FILE_SERVERS_HELP_ID);
294 dlg.SetContents(str, str2, resultFiles, servers);
298 CString GetAfsError(int code, const char *filename)
302 if (code == EINVAL) {
304 strMsg.Format("Invalid argument; it is possible that the file is not in AFS");
306 strMsg.Format("Invalid argument");
307 } else if (code == ENOENT) {
309 strMsg.Format("The file does not exist");
311 strMsg.Format("No such file returned");
312 } else if (code == EROFS) {
313 strMsg.Format("You can not change a backup or readonly volume");
314 } else if (code == EACCES || code == EPERM) {
315 strMsg.Format("You do not have the required rights to do this operation");
316 } else if (code == ENODEV) {
317 strMsg.Format("AFS service may not have started");
318 } else if (code == ESRCH) {
319 strMsg.Format("Cell name not recognized");
320 } else if (code == ETIMEDOUT) {
321 strMsg.Format("Connection timed out");
322 } else if (code == EPIPE) {
323 strMsg.Format("Volume name or ID not recognized");
325 strMsg.Format("Error 0x%x occurred", code);
332 /************************************************************************
333 ************************** ACL Code *************************************
334 ************************************************************************/
336 typedef char sec_rgy_name_t[1025]; /* A DCE definition */
339 struct AclEntry *next;
345 int dfs; // Originally true if a dfs acl; now also the type
346 // of the acl (1, 2, or 3, corresponding to object,
347 // initial dir, or initial object).
348 sec_rgy_name_t cell; // DFS cell name
351 struct AclEntry *pluslist;
352 struct AclEntry *minuslist;
355 int foldcmp (register char *a, register char *b)
361 if (t >= 'A' && t <= 'Z') t += 0x20;
362 if (u >= 'A' && u <= 'Z') u += 0x20;
363 if (t != u) return 1;
364 if (t == 0) return 0;
368 void ZapList(struct AclEntry *alist)
370 register struct AclEntry *tp, *np;
372 for (tp = alist; tp; tp = np) {
378 void ZapAcl (struct Acl *acl)
380 ZapList(acl->pluslist);
381 ZapList(acl->minuslist);
385 int PruneList (struct AclEntry **ae, int dfs)
387 struct AclEntry **lp = ae;
388 struct AclEntry *te, *ne;
391 for (te = *ae; te; te = ne) {
392 if ((!dfs && te->rights == 0) || te->rights == -1) {
407 char *SkipLine (register char *astr)
409 while (*astr != '\n')
417 /* tell if a name is 23 or -45 (digits or minus digits), which are bad names we must prune */
418 static BadName(register char *aname)
422 /* all must be '-' or digit to be bad */
423 while (tc = *aname++) {
424 if ((tc != '-') && (tc < '0' || tc > '9'))
431 CString GetRightsString(register LONG arights, int dfs)
436 if (arights & PRSFS_READ) str += "r";
437 if (arights & PRSFS_LOOKUP) str += "l";
438 if (arights & PRSFS_INSERT) str += "i";
439 if (arights & PRSFS_DELETE) str += "d";
440 if (arights & PRSFS_WRITE) str += "w";
441 if (arights & PRSFS_LOCK) str += "k";
442 if (arights & PRSFS_ADMINISTER) str += "a";
446 if (arights & DFS_READ) str += "r"; else str += "-";
447 if (arights & DFS_WRITE) str += "w"; else printf("-");
448 if (arights & DFS_EXECUTE) str += "x"; else printf("-");
449 if (arights & DFS_CONTROL) str += "c"; else printf("-");
450 if (arights & DFS_INSERT) str += "i"; else printf("-");
451 if (arights & DFS_DELETE) str += "d"; else printf("-");
452 if (arights & (DFS_USRALL)) str += "+";
459 char *AclToString(struct Acl *acl)
461 static char mydata[MAXSIZE];
462 char tstring[MAXSIZE];
467 sprintf(dfsstring, " dfs:%d %s", acl->dfs, acl->cell);
470 sprintf(mydata, "%d%s\n%d\n", acl->nplus, dfsstring, acl->nminus);
472 for(tp = acl->pluslist; tp; tp = tp->next) {
473 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
474 strcat(mydata, tstring);
477 for(tp = acl->minuslist; tp; tp = tp->next) {
478 sprintf(tstring, "%s %d\n", tp->name, tp->rights);
479 strcat(mydata, tstring);
485 struct Acl *EmptyAcl(const CString& strCellName)
487 register struct Acl *tp;
489 tp = (struct Acl *)malloc(sizeof (struct Acl));
490 tp->nplus = tp->nminus = 0;
491 tp->pluslist = tp->minuslist = 0;
493 strcpy(tp->cell, strCellName);
498 struct Acl *ParseAcl(char *astr)
500 int nplus, nminus, i, trights;
502 struct AclEntry *first, *last, *tl;
505 ta = (struct Acl *) malloc (sizeof (struct Acl));
507 sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
508 astr = SkipLine(astr);
509 sscanf(astr, "%d", &ta->nminus);
510 astr = SkipLine(astr);
517 for(i = 0; i < nplus; i++) {
518 sscanf(astr, "%100s %d", tname, &trights);
519 astr = SkipLine(astr);
520 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
523 strcpy(tl->name, tname);
524 tl->rights = trights;
530 ta->pluslist = first;
534 for(i=0; i < nminus; i++) {
535 sscanf(astr, "%100s %d", tname, &trights);
536 astr = SkipLine(astr);
537 tl = (struct AclEntry *) malloc(sizeof (struct AclEntry));
540 strcpy(tl->name, tname);
541 tl->rights = trights;
547 ta->minuslist = first;
552 /* clean up an access control list of its bad entries; return 1 if we made
553 any changes to the list, and 0 otherwise */
554 int CleanAcl(struct Acl *aa)
556 register struct AclEntry *te, **le, *ne;
561 /* Don't correct DFS ACL's for now */
565 /* prune out bad entries */
566 changes = 0; /* count deleted entries */
568 for(te = aa->pluslist; te; te = ne) {
570 if (BadName(te->name)) {
583 for(te = aa->minuslist; te; te = ne) {
585 if (BadName(te->name)) {
599 void CleanACL(CStringArray& names)
602 register struct Acl *ta;
603 struct ViceIoctl blob;
606 ShowMessageBox(IDS_CLEANACL_MSG, MB_OK, IDS_CLEANACL_MSG);
610 for (int i = 0; i < names.GetSize(); i++) {
611 blob.out_size = MAXSIZE;
615 code = pioctl(PCCHAR(names[i]), VIOCGETAL, &blob, 1);
617 ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONEXCLAMATION, 0, names[i], GetAfsError(errno));
621 ta = ParseAcl(space);
623 ShowMessageBox(IDS_CLEANACL_NOT_SUPPORTED, MB_ICONEXCLAMATION, IDS_CLEANACL_NOT_SUPPORTED, names[i]);
627 changes = CleanAcl(ta);
631 /* now set the acl */
632 blob.in = AclToString(ta);
633 blob.in_size = strlen((char *)blob.in) + 1;
636 code = pioctl(PCCHAR(names[i]), VIOCSETAL, &blob, 1);
638 if (errno == EINVAL) {
639 ShowMessageBox(IDS_CLEANACL_INVALID_ARG, MB_ICONEXCLAMATION, IDS_CLEANACL_INVALID_ARG, names[i]);
643 ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONEXCLAMATION, 0, names[i], GetAfsError(errno));
650 // Derived from fs.c's ListAclCmd
651 BOOL GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& strNegative)
654 register struct Acl *ta;
655 struct ViceIoctl blob;
657 int idf = 0; //getidf(as, parm_listacl_id);
661 blob.out_size = MAXSIZE;
663 blob.in = blob.out = space;
665 code = pioctl(PCCHAR(strDir), VIOCGETAL, &blob, 1);
667 ShowMessageBox(IDS_GETRIGHTS_ERROR, MB_ICONEXCLAMATION, IDS_GETRIGHTS_ERROR, strDir, GetAfsError(errno));
671 ta = ParseAcl(space);
673 ShowMessageBox(IDS_DFSACL_ERROR, MB_ICONEXCLAMATION, IDS_DFSACL_ERROR);
678 // printf(" Default cell = %s\n", ta->cell);
683 for (te = ta->pluslist; te; te = te->next) {
684 strNormal.Add(te->name);
685 strNormal.Add(GetRightsString(te->rights, ta->dfs));
689 if (ta->nminus > 0) {
690 for (te = ta->minuslist; te; te = te->next) {
691 strNegative.Add(te->name);
692 strNegative.Add(GetRightsString(te->rights, ta->dfs));
699 struct AclEntry *FindList(register struct AclEntry *pCurEntry, const char *entryName)
702 if (!foldcmp(pCurEntry->name, PCCHAR(entryName)))
704 pCurEntry = pCurEntry->next;
710 void ChangeList (struct Acl *pAcl, BYTE bNormalRights, const char *entryName, LONG nEntryRights)
715 struct AclEntry *pEntry;
719 pEntry = (bNormalRights ? pAcl->pluslist : pAcl->minuslist);
720 pEntry = FindList(pEntry, entryName);
722 /* Found the item already in the list. */
724 pEntry->rights = nEntryRights;
726 pAcl->nplus -= PruneList(&pAcl->pluslist, pAcl->dfs);
728 pAcl->nminus -= PruneList(&pAcl->minuslist, pAcl->dfs);
732 /* Otherwise we make a new item and plug in the new data. */
733 pEntry = (struct AclEntry *) malloc(sizeof (struct AclEntry));
736 strcpy(pEntry->name, entryName);
737 pEntry->rights = nEntryRights;
740 pEntry->next = pAcl->pluslist;
741 pAcl->pluslist = pEntry;
743 if (nEntryRights == 0 || nEntryRights == -1)
744 pAcl->nplus -= PruneList(&pAcl->pluslist, pAcl->dfs);
747 pEntry->next = pAcl->minuslist;
748 pAcl->minuslist = pEntry;
750 if (nEntryRights == 0)
751 pAcl->nminus -= PruneList(&pAcl->minuslist, pAcl->dfs);
755 enum rtype {add, destroy, deny};
757 LONG Convert(const register char *arights, int dfs, enum rtype *rtypep)
763 *rtypep = add; /* add rights, by default */
765 if (!strcmp(arights,"read"))
766 return PRSFS_READ | PRSFS_LOOKUP;
767 if (!strcmp(arights, "write"))
768 return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
769 if (!strcmp(arights, "mail"))
770 return PRSFS_INSERT | PRSFS_LOCK | PRSFS_LOOKUP;
771 if (!strcmp(arights, "all"))
772 return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
774 if (!strcmp(arights, "none")) {
775 *rtypep = destroy; /* Remove entire entry */
779 len = strlen(arights);
782 for (i = 0; i < len; i++) {
784 if (tc == 'r') mode |= PRSFS_READ;
785 else if (tc == 'l') mode |= PRSFS_LOOKUP;
786 else if (tc == 'i') mode |= PRSFS_INSERT;
787 else if (tc == 'd') mode |= PRSFS_DELETE;
788 else if (tc == 'w') mode |= PRSFS_WRITE;
789 else if (tc == 'k') mode |= PRSFS_LOCK;
790 else if (tc == 'a') mode |= PRSFS_ADMINISTER;
792 fprintf(stderr, "illegal rights character '%c'.\n", tc);
799 BOOL SaveACL(const CString& strCellName, const CString& strDir, const CStringArray& normal, const CStringArray& negative)
802 struct ViceIoctl blob;
810 pAcl = EmptyAcl(strCellName);
812 // Set its normal rights
813 for (int i = 0; i < normal.GetSize(); i += 2) {
814 rights = Convert(normal[i + 1], 0, &rtype);
815 ChangeList(pAcl, TRUE, normal[i], rights);
818 // Set its negative rights
819 for (i = 0; i < negative.GetSize(); i += 2) {
820 rights = Convert(negative[i + 1], 0, &rtype);
821 ChangeList(pAcl, FALSE, negative[i], rights);
825 blob.in = AclToString(pAcl);
827 blob.in_size = 1 + strlen((const char *)blob.in);
829 code = pioctl(PCCHAR(strDir), VIOCSETAL, &blob, 1);
832 ShowMessageBox(IDS_SAVE_ACL_EINVAL_ERROR, MB_ICONEXCLAMATION, IDS_SAVE_ACL_EINVAL_ERROR, strDir);
834 ShowMessageBox(IDS_SAVE_ACL_ERROR, MB_ICONEXCLAMATION, IDS_SAVE_ACL_ERROR, strDir, GetAfsError(errno, strDir));
842 BOOL CopyACL(const CString& strToDir, const CStringArray& normal, const CStringArray& negative, BOOL bClear)
845 struct ViceIoctl blob;
847 int idf = 0; // getidf(as, parm_copyacl_id);
851 // Get ACL to copy to
852 blob.out_size = MAXSIZE;
854 blob.in = blob.out = space;
856 code = pioctl(PCCHAR(strToDir), VIOCGETAL, &blob, 1);
858 ShowMessageBox(IDS_ACL_READ_ERROR, MB_ICONEXCLAMATION, IDS_ACL_READ_ERROR, strToDir, GetAfsError(errno, strToDir));
863 pToAcl = EmptyAcl(space);
865 pToAcl = ParseAcl(space);
870 ShowMessageBox(IDS_NO_DFS_COPY_ACL, MB_ICONEXCLAMATION, IDS_NO_DFS_COPY_ACL, strToDir);
878 for (int i = 0; i < normal.GetSize(); i += 2) {
879 LONG rights = Convert(normal[i + 1], 0, &rtype);
880 ChangeList(pToAcl, TRUE, normal[i], rights);
883 // Set negative rights
884 for (i = 0; i < negative.GetSize(); i += 2) {
885 LONG rights = Convert(negative[i + 1], 0, &rtype);
886 ChangeList(pToAcl, FALSE, normal[i], rights);
890 blob.in = AclToString(pToAcl);
892 blob.in_size = 1 + strlen((char *)blob.in);
894 code = pioctl(PCCHAR(strToDir), VIOCSETAL, &blob, 1);
898 ShowMessageBox(IDS_COPY_ACL_EINVAL_ERROR, MB_ICONEXCLAMATION, IDS_COPY_ACL_EINVAL_ERROR, strToDir);
900 ShowMessageBox(IDS_COPY_ACL_ERROR, MB_ICONEXCLAMATION, IDS_COPY_ACL_ERROR, strToDir, GetAfsError(errno, strToDir));
906 ShowMessageBox(IDS_COPY_ACL_OK, MB_OK, IDS_COPY_ACL_OK);
911 CString ParseMountPoint(const CString strFile, CString strMountPoint)
916 CString strMountPointInfo;
918 if (strMountPoint[0] == '#')
920 else if (strMountPoint[0] == '%')
921 strType = "Read/Write";
923 int nColon = strMountPoint.Find(':');
925 strCell = strMountPoint.Mid(1, nColon - 1);
926 strVolume = strMountPoint.Mid(nColon + 1);
928 strVolume = strMountPoint.Mid(1);
930 strMountPointInfo = strFile + "\t" + strVolume + "\t" + strCell + "\t" + strType;
932 return strMountPointInfo;
935 BOOL ListMount(CStringArray& files)
938 struct ViceIoctl blob;
940 char orig_name[1024]; /* Original name, may be modified */
941 char true_name[1024]; /* ``True'' dirname (e.g., symlink target) */
942 char parent_dir[1024]; /* Parent directory of true name */
943 register char *last_component; /* Last component of true name */
944 CStringArray mountPoints;
950 for (int i = 0; i < files.GetSize(); i++) {
951 strcpy(orig_name, files[i]);
952 strcpy(true_name, orig_name);
955 * Find rightmost slash, if any.
957 last_component = (char *)strrchr(true_name, '\\');
958 if (last_component) {
960 * Found it. Designate everything before it as the parent directory,
961 * everything after it as the final component.
963 strncpy(parent_dir, true_name, last_component - true_name + 1);
964 parent_dir[last_component - true_name + 1] = 0;
965 last_component++; /* Skip the slash */
969 * No slash appears in the given file name. Set parent_dir to the current
970 * directory, and the last component as the given name.
972 fs_ExtractDriveLetter(true_name, parent_dir);
973 strcat(parent_dir, ".");
974 last_component = true_name;
975 fs_StripDriveLetter(true_name, true_name, sizeof(true_name));
978 blob.in = last_component;
979 blob.in_size = strlen(last_component) + 1;
980 blob.out_size = MAXSIZE;
982 memset(space, 0, MAXSIZE);
984 code = pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
986 int nPos = strlen(space) - 1;
987 if (space[nPos] == '.')
989 mountPoints.Add(ParseMountPoint(StripPath(files[i]), space));
993 mountPoints.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(files[i])));
995 mountPoints.Add(GetMessageString(IDS_LIST_MOUNT_POINT_ERROR, GetAfsError(errno, StripPath(files[i]))));
1000 dlg.SetMountPoints(mountPoints);
1006 static BOOL InAFS(register char *apath)
1008 struct ViceIoctl blob;
1011 HOURGLASS hourglass;
1014 blob.out_size = MAXSIZE;
1017 code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
1019 if ((errno == EINVAL) || (errno == ENOENT))
1026 /* return a static pointer to a buffer */
1027 static char *Parent(char *apath)
1031 strcpy(tspace, apath);
1032 tp = strrchr(tspace, '\\');
1034 *(tp+1) = 0; /* lv trailing slash so Parent("k:\foo") is "k:\" not "k:" */
1037 fs_ExtractDriveLetter(apath, tspace);
1038 strcat(tspace, ".");
1044 BOOL MakeMount(const CString& strDir, const CString& strVolName, const CString& strCellName, BOOL bRW)
1047 register char *cellName;
1048 char localCellName[1000];
1049 struct ViceIoctl blob;
1051 HOURGLASS hourglass;
1053 ASSERT(strVolName.GetLength() < 64);
1059 if (as->parms[5].items && !as->parms[2].items) {
1060 fprintf(stderr,"fs: must provide cell when creating cellular mount point.\n");
1065 if (strCellName.GetLength() > 0) /* cell name specified */
1066 cellName = PCCHAR(strCellName);
1068 cellName = (char *) 0;
1070 if (!InAFS(Parent(PCCHAR(strDir)))) {
1071 ShowMessageBox(IDS_MAKE_MP_NOT_AFS_ERROR, MB_ICONEXCLAMATION, IDS_MAKE_MP_NOT_AFS_ERROR);
1077 blob.out_size = MAXSIZE;
1079 code = pioctl(Parent(PCCHAR(strDir)), VIOC_FILE_CELL_NAME, &blob, 1);
1082 strcpy(localCellName, (cellName? cellName : space));
1084 if (bRW) /* if -rw specified */
1089 /* If cellular mount point, prepend cell prefix */
1091 strcat(space, localCellName);
1095 strcat(space, strVolName); /* append volume name */
1096 strcat(space, "."); /* stupid convention; these end with a period */
1098 /* create symlink with a special pioctl for Windows NT, since it doesn't
1099 * have a symlink system call.
1102 blob.in_size = 1 + strlen(space);
1105 code = pioctl(PCCHAR(strDir), VIOC_AFS_CREATE_MT_PT, &blob, 0);
1108 ShowMessageBox(IDS_MOUNT_POINT_ERROR, MB_ICONEXCLAMATION, IDS_MOUNT_POINT_ERROR, GetAfsError(errno, strDir));
1116 * Delete AFS mount points. Variables are used as follows:
1117 * tbuffer: Set to point to the null-terminated directory name of the mount point
1118 * (or ``.'' if none is provided)
1119 * tp: Set to point to the actual name of the mount point to nuke.
1121 BOOL RemoveMount(CStringArray& files)
1123 register LONG code = 0;
1124 struct ViceIoctl blob;
1126 char lsbuffer[1024];
1129 CStringArray results;
1133 HOURGLASS hourglass;
1135 for (int i = 0; i < files.GetSize(); i++) {
1136 char szCurItem[1024];
1137 strcpy(szCurItem, files[i]);
1139 tp = (char *)strrchr(szCurItem, '\\');
1141 strncpy(tbuffer, szCurItem, code = tp - szCurItem + 1); /* the dir name */
1143 tp++; /* skip the slash */
1145 fs_ExtractDriveLetter(szCurItem, tbuffer);
1146 strcat(tbuffer, ".");
1148 fs_StripDriveLetter(tp, tp, 0);
1152 blob.in_size = strlen(tp)+1;
1153 blob.out = lsbuffer;
1154 blob.out_size = sizeof(lsbuffer);
1156 code = pioctl(tbuffer, VIOC_AFS_STAT_MT_PT, &blob, 0);
1159 if (errno == EINVAL)
1160 results.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR, StripPath(files[i])));
1162 results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
1163 continue; // don't bother trying
1168 blob.in_size = strlen(tp)+1;
1170 code = pioctl(tbuffer, VIOC_AFS_DELETE_MT_PT, &blob, 0);
1173 results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
1175 results.Add(GetMessageString(IDS_DELETED));
1178 LoadString (str, IDS_REMOVE_MP);
1179 LoadString (str2, IDS_REMOVE_MP_COLUMN);
1180 CResultsDlg dlg(REMOVE_MOUNT_POINTS_HELP_ID);
1181 dlg.SetContents(str, str2, StripPath(files), results);
1187 BOOL GetVolumeInfo(CString strFile, CVolInfo& volInfo)
1190 struct ViceIoctl blob;
1191 struct VolumeStatus *status;
1194 HOURGLASS hourglass;
1196 volInfo.m_strFilePath = strFile;
1197 volInfo.m_strFileName = StripPath(strFile);
1200 volInfo.m_strName = "VolumeName";
1202 volInfo.m_nQuota = 20 * 1024 * 1024;
1203 volInfo.m_nNewQuota = volInfo.m_nQuota;
1204 volInfo.m_nUsed = volInfo.m_nQuota / 2;
1205 volInfo.m_nPartSize = 50 * 1024 * 1024;
1206 volInfo.m_nPartFree = 30 * 1024 * 1024;
1207 volInfo.m_nDup = -1;
1211 blob.out_size = MAXSIZE;
1215 code = pioctl(PCCHAR(strFile), VIOCGETVOLSTAT, &blob, 1);
1217 volInfo.m_strErrorMsg = GetAfsError(errno, strFile);
1221 status = (VolumeStatus *)space;
1222 name = (char *)status + sizeof(*status);
1224 volInfo.m_strName = name;
1225 volInfo.m_nID = status->Vid;
1226 volInfo.m_nQuota = status->MaxQuota;
1227 volInfo.m_nNewQuota = status->MaxQuota;
1228 volInfo.m_nUsed = status->BlocksInUse;
1229 volInfo.m_nPartSize = status->PartMaxBlocks;
1230 volInfo.m_nPartFree = status->PartBlocksAvail;
1231 volInfo.m_nDup = -1;
1236 BOOL SetVolInfo(CVolInfo& volInfo)
1239 struct ViceIoctl blob;
1240 struct VolumeStatus *status;
1243 HOURGLASS hourglass;
1245 blob.out_size = MAXSIZE;
1246 blob.in_size = sizeof(*status) + 3; /* for the three terminating nulls */
1250 status = (VolumeStatus *)space;
1251 status->MinQuota = -1;
1252 status->MaxQuota = volInfo.m_nNewQuota;
1254 input = (char *)status + sizeof(*status);
1255 *(input++) = '\0'; /* never set name: this call doesn't change vldb */
1256 *(input++) = '\0'; // No offmsg
1257 *(input++) = '\0'; // No motd
1260 FILE *fp = OpenFile(szLogFileName, "a");
1262 fprintf(fp, "\nSetVolInfo() pioctl parms:\n");
1263 fprintf(fp, "\tpathp = %s\n\topcode = VIOCSETVOLSTAT (%d)\n\tblobp = %ld\n", PCCHAR(volInfo.m_strFilePath), VIOCSETVOLSTAT, &blob);
1264 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);
1265 fprintf(fp, "\t\t\tstatus->MinQuota = %ld\n", status->MinQuota);
1266 fprintf(fp, "\t\t\tstatus->MaxQuota = %ld\n", status->MaxQuota);
1267 fprintf(fp, "\t\t\tOther status fields aren't set\n");
1268 fprintf(fp, "\t\t\t3 nulls follow the VolumeStatus structure.\n");
1269 fprintf(fp, "\tfollow = 1\n");
1274 code = pioctl(PCCHAR(volInfo.m_strFilePath), VIOCSETVOLSTAT, &blob, 1);
1276 ShowMessageBox(IDS_SET_QUOTA_ERROR, MB_ICONEXCLAMATION, IDS_SET_QUOTA_ERROR, GetAfsError(errno, volInfo.m_strName));
1283 int GetCellName(char *cellNamep, struct afsconf_cell *infop)
1285 strcpy(infop->name, cellNamep);
1289 BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast)
1292 struct ViceIoctl blob;
1295 struct afsconf_cell info;
1296 struct chservinfo checkserv;
1298 HOURGLASS hourglass;
1300 memset(&checkserv, 0, sizeof(struct chservinfo));
1301 blob.in_size = sizeof(struct chservinfo);
1302 blob.in = (caddr_t)&checkserv;
1304 blob.out_size = MAXSIZE;
1306 memset(space, 0, sizeof(LONG)); /* so we assure zero when nothing is copied back */
1308 /* prepare flags for checkservers command */
1309 if (nCellsToCheck == LOCAL_CELL)
1310 temp = 2; /* default to checking local cell only */
1311 else if (nCellsToCheck == ALL_CELLS)
1312 temp &= ~2; /* turn off local cell check */
1315 temp |= 1; /* set fast flag */
1317 checkserv.magic = 0x12345678; /* XXX */
1318 checkserv.tflags = temp;
1320 /* now copy in optional cell name, if specified */
1321 if (nCellsToCheck == SPECIFIC_CELL) {
1322 GetCellName(PCCHAR(strCellName), &info);
1323 strcpy(checkserv.tbuffer,info.name);
1324 checkserv.tsize = strlen(info.name) + 1;
1326 strcpy(checkserv.tbuffer, "\0");
1327 checkserv.tsize = 0;
1330 checkserv.tinterval = -1; /* don't change current interval */
1332 code = pioctl(0, VIOCCKSERV, &blob, 1);
1334 ShowMessageBox(IDS_CHECK_SERVERS_ERROR, MB_ICONEXCLAMATION, IDS_CHECK_SERVERS_ERROR, GetAfsError(errno, CString()));
1338 memcpy(&temp, space, sizeof(LONG));
1341 ShowMessageBox(IDS_ALL_SERVERS_RUNNING, MB_OK, IDS_ALL_SERVERS_RUNNING);
1345 CStringArray servers;
1346 for (j = 0; j < MAXHOSTS; j++) {
1347 memcpy(&temp, space + j * sizeof(LONG), sizeof(LONG));
1351 char *name = hostutil_GetNameByINet(temp);
1355 CDownServersDlg dlg;
1356 dlg.SetServerNames(servers);
1362 BOOL GetTokenInfo(CStringArray& tokenInfo)
1367 long tokenExpireTime;
1371 struct ktc_principal serviceName, clientName;
1372 struct ktc_token token;
1374 CString strTokenInfo;
1375 CString strUserName;
1376 CString strCellName;
1379 // tokenInfo.Add("");
1383 HOURGLASS hourglass;
1385 // printf("\nTokens held by the Cache Manager:\n\n");
1387 current_time = time(0);
1390 rc = ktc_ListTokens(cellNum, &cellNum, &serviceName);
1391 if (rc == KTC_NOENT) {
1393 // printf(" --End of list --\n");
1396 else if (rc == KTC_NOCM) {
1397 ShowMessageBox(IDS_GET_TOKENS_NO_AFS_SERVICE);
1398 // printf("AFS service may not have started\n");
1402 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR, MB_ICONEXCLAMATION, IDS_GET_TOKENS_UNEXPECTED_ERROR, rc);
1404 // printf("Unexpected error, code %d\n", rc);
1408 rc = ktc_GetToken(&serviceName, &token, sizeof(token), &clientName);
1410 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR2, MB_ICONEXCLAMATION, IDS_GET_TOKENS_UNEXPECTED_ERROR2,
1411 serviceName.name, serviceName.instance, serviceName.cell, rc);
1415 tokenExpireTime = token.endTime;
1417 strcpy(userName, clientName.name);
1418 if (clientName.instance[0] != 0) {
1419 strcat(userName, ".");
1420 strcat(userName, clientName.instance);
1423 BOOL bShowName = FALSE;
1425 if (userName[0] == '\0')
1426 ; //printf("Tokens");
1427 // AFS ID is not returned at this time.
1428 // else if (strncmp(userName, "AFS ID", 6) == 0)
1429 // printf("User's (%s) tokens", userName);
1430 // sscanf(userName, "(AFS ID %s)", szAfsID);
1431 else if (strncmp(userName, "Unix UID", 8) == 0)
1432 ; //printf("Tokens");
1434 strUserName = userName;
1435 // printf("User %s's tokens", userName);
1437 // printf(" for %s%s%s@%s ", serviceName.name, serviceName.instance[0] ? "." : "", serviceName.instance, serviceName.cell);
1438 strCellName = serviceName.cell;
1440 if (tokenExpireTime <= current_time)
1441 strExpir = "[>> Expired <<]";
1442 // printf("[>> Expired <<]\n");
1444 expireString = ctime(&tokenExpireTime);
1445 expireString += 4; /* Skip day of week */
1446 expireString[12] = '\0'; /* Omit secs & year */
1447 // printf("[Expires %s]\n", expireString);
1448 strExpir.Format("%s", expireString);
1451 strTokenInfo = strUserName + "\t" + strCellName + "\t" + strExpir + "\t" + strCellName;
1452 tokenInfo.Add(strTokenInfo);
1456 // printf("Press <Enter> or <Return> when finished: ");
1461 BOOL IsPathInAfs(const CString& strPath)
1463 struct ViceIoctl blob;
1467 blob.out_size = MAXSIZE;
1470 code = pioctl(PCCHAR(strPath), VIOC_FILE_CELL_NAME, &blob, 1);
1472 if ((errno == EINVAL) || (errno == ENOENT)) return FALSE;