2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
15 #include <afsconfig.h>
16 #include <afs/param.h>
26 #include "results_dlg.h"
27 #include "volume_inf.h"
28 #include "mount_points_dlg.h"
29 #include "symlinks_dlg.h"
30 #include "hourglass.h"
31 #include "down_servers_dlg.h"
34 #include <rx/rx_globals.h>
37 #include <afs/afsint.h>
38 #include <afs/afs_consts.h>
39 #include <afs/cellconfig.h>
40 #include <afs/ptserver.h>
41 #include <afs/ptuser.h>
42 #include <afs/vldbint.h>
43 #include <afs/volser.h>
45 #include <WINNT\afsreg.h>
50 #include <cm_scache.h>
52 #include <cm_config.h>
55 #define STRSAFE_NO_DEPRECATE
59 * the NO_CALLER symbol is used to document functions
60 * that are present in this file but have no caller
65 #define PCCHAR(str) ((char *)(const char *)(str))
66 #define VL_NOENT (363524L)
69 #define MAXINSIZE 1300 /* pioctl complains if data is larger than this */
70 #define VMSGSIZE 128 /* size of msg buf in volume hdr */
72 #define MAXCELLCHARS 64
73 #define MAXHOSTCHARS 64
74 #define MAXHOSTSPERCELL 8
76 static struct ubik_client
*uclient
;
77 static int rxInitDone
= 0;
78 static char pn
[] = "fs";
80 // #define LOGGING_ON // Enable this to log certain pioctl calls
83 static char *szLogFileName
= "afsguilog.txt";
87 class CStringUtf8
: public CStringA
90 CStringUtf8(const CStringW
& csw
) : CStringA()
95 CStringUtf8(const char * cp
) : CStringA(cp
) {}
97 CStringUtf8() :CStringA() {}
99 void SetString(const CStringW
& csw
)
104 rv
= WideCharToMultiByte(CP_UTF8
, 0, csw
, -1,
105 buffer
, sizeof(buffer
),
109 CStringA::SetString(buffer
);
111 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
114 cb_req
= WideCharToMultiByte(CP_UTF8
, 0, csw
, -1, NULL
, 0, NULL
, FALSE
);
118 WideCharToMultiByte(CP_UTF8
, 0, csw
, -1, CStringA::GetBuffer(cb_req
), cb_req
, NULL
, FALSE
);
119 CStringA::ReleaseBuffer();
129 static CString
_Utf8ToCString(const char * ustr
)
134 cch
= MultiByteToWideChar(CP_UTF8
, 0, ustr
, -1, NULL
, 0);
141 cch
= MultiByteToWideChar(CP_UTF8
, 0, ustr
, -1, cs
.GetBuffer(cch
), cch
);
149 pioctl_T(const CString
& path
, long opcode
, struct ViceIoctl
* blob
, int follow
)
151 CStringUtf8
upath(path
);
153 return pioctl_utf8(PCCHAR(upath
), opcode
, blob
, follow
);
156 #define Utf8ToCString(cs) CStringUtf8::_Utf8ToCString(cs)
158 #define pioctl_T(path, op, vblob, follow) pioctl(PCCHAR(path), op, vblob, follow)
159 #define Utf8ToCString(cs) (cs)
163 VLDBInit(int noAuthFlag
, struct afsconf_cell
*info
)
167 code
= ugen_ClientInit(noAuthFlag
, (char *)AFSDIR_CLIENT_ETC_DIRPATH
,
168 info
->name
, 0, &uclient
,
169 NULL
, pn
, rxkad_clear
,
170 VLDB_MAXSERVERS
, AFSCONF_VLDBSERVICE
, 50,
171 0, 0, USER_SERVICE_ID
);
177 OpenFile(char *file
, char *rwp
)
184 code
= GetWindowsDirectoryA(wdir
, sizeof(wdir
));
185 if (code
== 0 || code
> sizeof(wdir
))
188 /* add trailing backslash, if required */
190 if (wdir
[tlen
- 1] != '\\')
195 fp
= fopen(wdir
, rwp
);
200 CString
StripPath(const CString
& strPath
)
202 int nIndex
= strPath
.ReverseFind('\\');
204 CString strFile
= strPath
.Mid(nIndex
+ 1);
205 if (strFile
.IsEmpty())
212 StripPath(CStringArray
& files
)
214 for (int i
= 0; i
< files
.GetSize(); i
++)
215 files
[i
] = StripPath(files
[i
]);
221 Flush(const CStringArray
& files
)
224 struct ViceIoctl blob
;
229 for (int i
= 0; i
< files
.GetSize(); i
++) {
230 blob
.in_size
= blob
.out_size
= 0;
232 code
= pioctl_T(files
[i
], VIOCFLUSH
, &blob
, 0);
236 ShowMessageBox(IDS_FLUSH_FAILED
, MB_ICONERROR
, IDS_FLUSH_FAILED
, files
[i
]);
238 ShowMessageBox(IDS_FLUSH_ERROR
, MB_ICONERROR
, IDS_FLUSH_ERROR
, files
[i
], strerror(errno
));
243 ShowMessageBox(IDS_FLUSH_OK
, MB_ICONINFORMATION
, IDS_FLUSH_OK
);
247 FlushVolume(const CStringArray
& files
)
250 struct ViceIoctl blob
;
255 for (int i
= 0; i
< files
.GetSize(); i
++) {
256 blob
.in_size
= blob
.out_size
= 0;
258 code
= pioctl_T(files
[i
], VIOC_FLUSHVOLUME
, &blob
, 0);
261 ShowMessageBox(IDS_FLUSH_VOLUME_ERROR
, MB_ICONERROR
, IDS_FLUSH_VOLUME_ERROR
, files
[i
], strerror(errno
));
266 ShowMessageBox(IDS_FLUSH_VOLUME_OK
, MB_ICONINFORMATION
, IDS_FLUSH_VOLUME_OK
);
270 WhichCell(CStringArray
& files
)
273 struct ViceIoctl blob
;
278 CStringArray results
;
284 for (int i
= 0; i
< files
.GetSize(); i
++) {
285 char space
[AFS_PIOCTL_MAXSIZE
];
288 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
291 code
= pioctl_T(files
[i
], VIOC_FILE_CELL_NAME
, &blob
, 1);
293 if (code
== ENOENT
) {
294 LoadString (str
, IDS_CANT_GET_CELL
);
297 results
.Add(GetAfsError(errno
));
299 space
[AFS_PIOCTL_MAXSIZE
- 1] = '\0';
300 results
.Add(Utf8ToCString(space
));
304 LoadString (str
, IDS_SHOW_CELL
);
305 LoadString (str2
, IDS_SHOW_CELL_COLUMN
);
306 CResultsDlg
dlg(SHOW_CELL_HELP_ID
);
307 dlg
.SetContents(str
, str2
, StripPath(files
), results
);
314 char space
[AFS_PIOCTL_MAXSIZE
];
316 struct ViceIoctl blob
;
321 blob
.in
= (char *) 0;
322 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
325 code
= pioctl((char *) 0, VIOC_GET_WS_CELL
, &blob
, 1);
328 * Cell name is left in 'space' as side effect.
329 * At present no callers of this function.
337 struct ViceIoctl blob
;
341 code
= pioctl(0, VIOCCKBACK
, &blob
, 1);
343 ShowMessageBox(IDS_CHECK_VOLUMES_ERROR
, MB_ICONERROR
, IDS_CHECK_VOLUMES_ERROR
, GetAfsError(errno
, CString()));
347 ShowMessageBox(IDS_CHECK_VOLUMES_OK
, MB_OK
|MB_ICONINFORMATION
, IDS_CHECK_VOLUMES_OK
);
353 SetCacheSizeCmd(LONG nNewCacheSize
)
356 struct ViceIoctl blob
;
360 blob
.in
= (char *) &nNewCacheSize
;
361 blob
.in_size
= sizeof(LONG
);
364 code
= pioctl(0, VIOCSETCACHESIZE
, &blob
, 1);
366 /* error handling? */
370 WhereIs(CStringArray
& files
)
373 struct ViceIoctl blob
;
374 CStringArray servers
;
375 CStringArray resultFiles
;
381 for (int i
= 0; i
< files
.GetSize(); i
++) {
382 char space
[AFS_PIOCTL_MAXSIZE
];
384 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
387 memset(space
, 0, sizeof(space
));
389 code
= pioctl_T(files
[i
], VIOCWHEREIS
, &blob
, 1);
391 resultFiles
.Add(StripPath(files
[i
]));
392 servers
.Add(GetAfsError(errno
));
396 LONG
*hosts
= (LONG
*)space
;
400 for (int j
= 0; j
< AFS_MAXHOSTS
; j
++) {
403 char *hostName
= hostutil_GetNameByINet(hosts
[j
]);
405 resultFiles
.Add(StripPath(files
[i
]));
408 resultFiles
.Add(" ");
409 servers
.Add(hostName
);
413 LoadString (str
, IDS_SHOW_FS
);
414 LoadString (str2
, IDS_SHOW_FS_COLUMN
);
415 CResultsDlg
dlg(SHOW_FILE_SERVERS_HELP_ID
);
416 dlg
.SetContents(str
, str2
, resultFiles
, servers
);
421 CMtoUNIXerror(int cm_code
)
424 case CM_ERROR_TIMEDOUT
:
426 case CM_ERROR_NOACCESS
:
428 case CM_ERROR_NOSUCHFILE
:
434 case CM_ERROR_EXISTS
:
436 case CM_ERROR_CROSSDEVLINK
:
438 case CM_ERROR_NOTDIR
:
442 case CM_ERROR_READONLY
:
444 case CM_ERROR_WOULDBLOCK
:
446 case CM_ERROR_NOSUCHCELL
:
447 return ESRCH
; /* hack */
448 case CM_ERROR_NOSUCHVOLUME
:
449 return EPIPE
; /* hack */
450 case CM_ERROR_NOMORETOKENS
:
451 return EDOM
; /* hack */
452 case CM_ERROR_TOOMANYBUFS
:
453 return EFBIG
; /* hack */
455 if (cm_code
> 0 && cm_code
< EILSEQ
)
463 GetAfsError(int code
, const TCHAR
*filename
)
467 code
= CMtoUNIXerror(code
);
469 if (code
== EINVAL
) {
471 strMsg
.Format(_T("Invalid argument; it is possible that the file is not in AFS"));
473 strMsg
.Format(_T("Invalid argument"));
474 } else if (code
== ENOENT
) {
476 strMsg
.Format(_T("The file does not exist"));
478 strMsg
.Format(_T("No such file returned"));
479 } else if (code
== EROFS
) {
480 strMsg
.Format(_T("You can not change a backup or readonly volume"));
481 } else if (code
== EACCES
|| code
== EPERM
) {
482 strMsg
.Format(_T("You do not have the required rights to do this operation"));
483 } else if (code
== ENODEV
) {
484 strMsg
.Format(_T("AFS service may not have started"));
485 } else if (code
== ESRCH
) {
486 strMsg
.Format(_T("Cell name not recognized"));
487 } else if (code
== ETIMEDOUT
) {
488 strMsg
.Format(_T("Connection timed out"));
489 } else if (code
== EPIPE
) {
490 strMsg
.Format(_T("Volume name or ID not recognized"));
492 strMsg
.Format(_T("Error 0x%x occurred"), code
);
500 foldcmp (char *a
, char *b
)
506 if (t
>= 'A' && t
<= 'Z') t
+= 0x20;
507 if (u
>= 'A' && u
<= 'Z') u
+= 0x20;
508 if (t
!= u
) return 1;
509 if (t
== 0) return 0;
514 GetRightsString(LONG arights
, int dfs
)
519 if (arights
& PRSFS_READ
) str
+= _T("r");
520 if (arights
& PRSFS_LOOKUP
) str
+= _T("l");
521 if (arights
& PRSFS_INSERT
) str
+= _T("i");
522 if (arights
& PRSFS_DELETE
) str
+= _T("d");
523 if (arights
& PRSFS_WRITE
) str
+= _T("w");
524 if (arights
& PRSFS_LOCK
) str
+= _T("k");
525 if (arights
& PRSFS_ADMINISTER
) str
+= _T("a");
529 if (arights & DFS_READ) str += _T("r"); else str += _T("-");
530 if (arights & DFS_WRITE) str += _T("w"); else printf(_T("-"));
531 if (arights & DFS_EXECUTE) str += _T("x"); else printf(_T("-"));
532 if (arights & DFS_CONTROL) str += _T("c"); else printf(_T("-"));
533 if (arights & DFS_INSERT) str += _T("i"); else printf(_T("-"));
534 if (arights & DFS_DELETE) str += _T("d"); else printf(_T("-"));
535 if (arights & (DFS_USRALL)) str += _T("+");
543 EmptyAcl(const CString
& strCellName
)
546 CStringUtf8
ustrCell(strCellName
);
548 tp
= (struct Acl
*)malloc(sizeof (struct Acl
));
549 tp
->nplus
= tp
->nminus
= 0;
550 tp
->pluslist
= tp
->minuslist
= 0;
552 StringCbCopyA(tp
->cell
, sizeof(tp
->cell
), ustrCell
);
558 CleanACL(CStringArray
& names
)
562 struct ViceIoctl blob
;
565 ShowMessageBox(IDS_CLEANACL_MSG
, MB_OK
|MB_ICONINFORMATION
, IDS_CLEANACL_MSG
);
569 for (int i
= 0; i
< names
.GetSize(); i
++) {
570 char space
[AFS_PIOCTL_MAXSIZE
];
572 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
576 code
= pioctl_T(names
[i
], VIOCGETAL
, &blob
, 1);
578 ShowMessageBox(IDS_CLEANACL_ERROR
, MB_ICONERROR
, 0, names
[i
], GetAfsError(errno
));
582 ta
= ParseAcl(space
, AFS_PIOCTL_MAXSIZE
);
584 ShowMessageBox(IDS_INVALID_ACL_DATA
, MB_ICONERROR
, IDS_INVALID_ACL_DATA
);
588 ShowMessageBox(IDS_CLEANACL_NOT_SUPPORTED
, MB_ICONERROR
, IDS_CLEANACL_NOT_SUPPORTED
, names
[i
]);
592 changes
= CleanAcl(ta
, NULL
);
596 /* now set the acl */
597 blob
.in
= AclToString(ta
);
598 blob
.in_size
= strlen((char *)blob
.in
) + 1;
601 code
= pioctl_T(names
[i
], VIOCSETAL
, &blob
, 1);
603 if (errno
== EINVAL
) {
604 ShowMessageBox(IDS_CLEANACL_INVALID_ARG
, MB_ICONERROR
, IDS_CLEANACL_INVALID_ARG
, names
[i
]);
608 ShowMessageBox(IDS_CLEANACL_ERROR
, MB_ICONERROR
, 0, names
[i
], GetAfsError(errno
));
615 // Derived from fs.c's ListAclCmd
617 GetRights(const CString
& strDir
, CStringArray
& strNormal
, CStringArray
& strNegative
)
621 struct ViceIoctl blob
;
623 int idf
= 0; //getidf(as, parm_listacl_id);
624 char space
[AFS_PIOCTL_MAXSIZE
];
627 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
629 blob
.in
= blob
.out
= space
;
631 code
= pioctl_T(strDir
, VIOCGETAL
, &blob
, 1);
633 ShowMessageBox(IDS_GETRIGHTS_ERROR
, MB_ICONERROR
, IDS_GETRIGHTS_ERROR
, strDir
, GetAfsError(errno
));
637 ta
= ParseAcl(space
, AFS_PIOCTL_MAXSIZE
);
639 ShowMessageBox(IDS_INVALID_ACL_DATA
, MB_ICONERROR
, IDS_INVALID_ACL_DATA
);
643 ShowMessageBox(IDS_DFSACL_ERROR
, MB_ICONERROR
, IDS_DFSACL_ERROR
);
648 // printf(" Default cell = %s\n", ta->cell);
653 for (te
= ta
->pluslist
; te
; te
= te
->next
) {
654 strNormal
.Add(te
->name
);
655 strNormal
.Add(GetRightsString(te
->rights
, ta
->dfs
));
659 if (ta
->nminus
> 0) {
660 for (te
= ta
->minuslist
; te
; te
= te
->next
) {
661 strNegative
.Add(te
->name
);
662 strNegative
.Add(GetRightsString(te
->rights
, ta
->dfs
));
670 FindList(struct AclEntry
*pCurEntry
, const char *entryName
)
673 if (!foldcmp(pCurEntry
->name
, PCCHAR(entryName
)))
675 pCurEntry
= pCurEntry
->next
;
682 ChangeList(struct Acl
*pAcl
, BYTE bNormalRights
, const CString
& entryName
, LONG nEntryRights
)
687 struct AclEntry
*pEntry
;
688 CStringUtf8
uEntryName(entryName
);
692 pEntry
= (bNormalRights
? pAcl
->pluslist
: pAcl
->minuslist
);
693 pEntry
= FindList(pEntry
, uEntryName
);
695 /* Found the item already in the list. */
697 pEntry
->rights
= nEntryRights
;
699 pAcl
->nplus
-= PruneList(&pAcl
->pluslist
, pAcl
->dfs
);
701 pAcl
->nminus
-= PruneList(&pAcl
->minuslist
, pAcl
->dfs
);
705 /* Otherwise we make a new item and plug in the new data. */
706 pEntry
= (struct AclEntry
*) malloc(sizeof (struct AclEntry
));
709 strcpy(pEntry
->name
, uEntryName
);
710 pEntry
->rights
= nEntryRights
;
713 pEntry
->next
= pAcl
->pluslist
;
714 pAcl
->pluslist
= pEntry
;
716 if (nEntryRights
== 0 || nEntryRights
== -1)
717 pAcl
->nplus
-= PruneList(&pAcl
->pluslist
, pAcl
->dfs
);
720 pEntry
->next
= pAcl
->minuslist
;
721 pAcl
->minuslist
= pEntry
;
723 if (nEntryRights
== 0)
724 pAcl
->nminus
-= PruneList(&pAcl
->minuslist
, pAcl
->dfs
);
729 Convert(const CString
& strRights
, int dfs
, enum rtype
*rtypep
)
734 *rtypep
= add
; /* add rights, by default */
736 if (strRights
== _T("read"))
737 return PRSFS_READ
| PRSFS_LOOKUP
;
738 if (strRights
== _T("write"))
739 return PRSFS_READ
| PRSFS_LOOKUP
| PRSFS_INSERT
| PRSFS_DELETE
| PRSFS_WRITE
| PRSFS_LOCK
;
740 if (strRights
== _T("mail"))
741 return PRSFS_INSERT
| PRSFS_LOCK
| PRSFS_LOOKUP
;
742 if (strRights
== _T("all"))
743 return PRSFS_READ
| PRSFS_LOOKUP
| PRSFS_INSERT
| PRSFS_DELETE
| PRSFS_WRITE
| PRSFS_LOCK
| PRSFS_ADMINISTER
;
745 if (strRights
== _T("none")) {
746 *rtypep
= destroy
; /* Remove entire entry */
750 len
= strRights
.GetLength();
753 for (i
= 0; i
< len
; i
++) {
754 TCHAR c
= strRights
[i
];
755 if (c
== _T('r')) mode
|= PRSFS_READ
;
756 else if (c
== _T('l')) mode
|= PRSFS_LOOKUP
;
757 else if (c
== _T('i')) mode
|= PRSFS_INSERT
;
758 else if (c
== _T('d')) mode
|= PRSFS_DELETE
;
759 else if (c
== _T('w')) mode
|= PRSFS_WRITE
;
760 else if (c
== _T('k')) mode
|= PRSFS_LOCK
;
761 else if (c
== _T('a')) mode
|= PRSFS_ADMINISTER
;
763 fprintf(stderr
, "illegal rights character '%c'.\n", c
);
771 SaveACL(const CString
& strCellName
, const CString
& strDir
, const CStringArray
& normal
, const CStringArray
& negative
)
774 struct ViceIoctl blob
;
782 pAcl
= EmptyAcl(strCellName
);
784 // Set its normal rights
786 for (i
= 0; i
< normal
.GetSize(); i
+= 2) {
787 rights
= Convert(normal
[i
+ 1], 0, &rtype
);
788 ChangeList(pAcl
, TRUE
, normal
[i
], rights
);
791 // Set its negative rights
792 for (i
= 0; i
< negative
.GetSize(); i
+= 2) {
793 rights
= Convert(negative
[i
+ 1], 0, &rtype
);
794 ChangeList(pAcl
, FALSE
, negative
[i
], rights
);
798 blob
.in
= AclToString(pAcl
);
800 blob
.in_size
= 1 + strlen((const char *)blob
.in
);
802 code
= pioctl_T(strDir
, VIOCSETAL
, &blob
, 1);
805 ShowMessageBox(IDS_SAVE_ACL_EINVAL_ERROR
, MB_ICONERROR
, IDS_SAVE_ACL_EINVAL_ERROR
, strDir
);
807 ShowMessageBox(IDS_SAVE_ACL_ERROR
, MB_ICONERROR
, IDS_SAVE_ACL_ERROR
, strDir
, GetAfsError(errno
, strDir
));
816 CopyACL(const CString
& strToDir
, const CStringArray
& normal
, const CStringArray
& negative
, BOOL bClear
)
819 struct ViceIoctl blob
;
821 int idf
= 0; // getidf(as, parm_copyacl_id);
822 char space
[AFS_PIOCTL_MAXSIZE
];
825 // Get ACL to copy to
826 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
828 blob
.in
= blob
.out
= space
;
830 code
= pioctl_T(strToDir
, VIOCGETAL
, &blob
, 1);
832 ShowMessageBox(IDS_ACL_READ_ERROR
, MB_ICONERROR
, IDS_ACL_READ_ERROR
, strToDir
, GetAfsError(errno
, strToDir
));
837 pToAcl
= EmptyAcl(space
);
839 pToAcl
= ParseAcl(space
, AFS_PIOCTL_MAXSIZE
);
841 if (pToAcl
== NULL
) {
842 ShowMessageBox(IDS_INVALID_ACL_DATA
, MB_ICONERROR
, IDS_INVALID_ACL_DATA
);
846 CleanAcl(pToAcl
, NULL
);
849 ShowMessageBox(IDS_NO_DFS_COPY_ACL
, MB_ICONERROR
, IDS_NO_DFS_COPY_ACL
, strToDir
);
858 for (i
= 0; i
< normal
.GetSize(); i
+= 2) {
859 LONG rights
= Convert(normal
[i
+ 1], 0, &rtype
);
860 ChangeList(pToAcl
, TRUE
, normal
[i
], rights
);
863 // Set negative rights
864 for (i
= 0; i
< negative
.GetSize(); i
+= 2) {
865 LONG rights
= Convert(negative
[i
+ 1], 0, &rtype
);
866 ChangeList(pToAcl
, FALSE
, normal
[i
], rights
);
870 blob
.in
= AclToString(pToAcl
);
872 blob
.in_size
= 1 + strlen((char *)blob
.in
);
874 code
= pioctl_T(strToDir
, VIOCSETAL
, &blob
, 1);
878 ShowMessageBox(IDS_COPY_ACL_EINVAL_ERROR
, MB_ICONERROR
, IDS_COPY_ACL_EINVAL_ERROR
, strToDir
);
880 ShowMessageBox(IDS_COPY_ACL_ERROR
, MB_ICONERROR
, IDS_COPY_ACL_ERROR
, strToDir
, GetAfsError(errno
, strToDir
));
886 ShowMessageBox(IDS_COPY_ACL_OK
, MB_OK
|MB_ICONINFORMATION
, IDS_COPY_ACL_OK
);
892 ParseMountPoint(const CString strFile
, CString strMountPoint
)
897 CString strMountPointInfo
;
899 if (strMountPoint
[0] == '#')
901 else if (strMountPoint
[0] == '%')
902 strType
= "Read/Write";
904 int nColon
= strMountPoint
.Find(':');
906 strCell
= strMountPoint
.Mid(1, nColon
- 1);
907 strVolume
= strMountPoint
.Mid(nColon
+ 1);
909 strVolume
= strMountPoint
.Mid(1);
910 strCell
= _T("(local)");
913 strMountPointInfo
= _T("=> ") + strVolume
+ _T(" : ") + strCell
+ _T(" cell [") + strType
+ _T("]");
915 return strMountPointInfo
;
919 ParseSymlink(const CString strFile
, CString strSymlink
)
921 CString strSymlinkInfo
;
923 strSymlinkInfo
= _T("-> ") + strSymlink
;
925 return strSymlinkInfo
;
929 GetFID(const CString
& path
, CString
& fidstring
, BOOL bLiteral
)
931 struct ViceIoctl blob
;
932 cm_ioctlQueryOptions_t options
;
936 memset(&options
, 0, sizeof(options
));
937 options
.size
= sizeof(options
);
938 options
.field_flags
|= CM_IOCTL_QOPTS_FIELD_LITERAL
;
939 options
.literal
= bLiteral
? 1 : 0;
940 blob
.in_size
= options
.size
; /* no variable length data */
942 blob
.out_size
= sizeof(cm_fid_t
);
943 blob
.out
= (char *) &fid
;
945 code
= pioctl_T(path
, VIOCGETFID
, &blob
, 1);
948 fidstring
.Format( TEXT("%lu.%lu.%lu"),
958 IsPathInAfs(const CString
& strPath
)
960 struct ViceIoctl blob
;
961 cm_ioctlQueryOptions_t options
;
967 memset(&options
, 0, sizeof(options
));
968 options
.size
= sizeof(options
);
969 options
.field_flags
|= CM_IOCTL_QOPTS_FIELD_LITERAL
;
971 blob
.in_size
= options
.size
; /* no variable length data */
973 blob
.out_size
= sizeof(cm_fid_t
);
974 blob
.out
= (char *) &fid
;
976 code
= pioctl_T(strPath
, VIOCGETFID
, &blob
, 1);
978 if ((errno
== EINVAL
) || (errno
== ENOENT
))
985 IsFreelanceRoot(const CString
& apath
)
987 struct ViceIoctl blob
;
989 char space
[AFS_PIOCTL_MAXSIZE
];
992 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
995 code
= pioctl_T(apath
, VIOC_FILE_CELL_NAME
, &blob
, 1);
997 return !strcmp("Freelance.Local.Root",space
);
998 return 1; /* assume it is because it is more restrictive that way */
1004 static char buffer
[1024] = "AFS";
1010 code
= RegOpenKeyEx(HKEY_LOCAL_MACHINE
, AFSREG_CLT_SVC_PARAM_SUBKEY
,
1011 0, (IsWow64()?KEY_WOW64_64KEY
:0)|KEY_QUERY_VALUE
, &parmKey
);
1012 if (code
== ERROR_SUCCESS
) {
1013 dummyLen
= sizeof(buffer
);
1014 code
= RegQueryValueExA(parmKey
, "NetbiosName", NULL
, NULL
,
1015 (LPBYTE
)buffer
, &dummyLen
);
1016 RegCloseKey (parmKey
);
1018 strcpy(buffer
, "AFS");
1024 FixNetbiosPath(CString
& path
)
1026 if (!IsPathInAfs(path
)) {
1028 const char * nbname
= NetbiosName();
1030 nbroot
.Format(_T("\\\\%s\\"), nbname
);
1032 if (nbroot
.CompareNoCase(path
) == 0) {
1033 path
.Append(_T("all\\"));
1038 #define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins"
1043 static BOOL fAdmin
= FALSE
;
1044 static BOOL fTested
= FALSE
;
1048 /* Obtain the SID for the AFS client admin group. If the group does
1049 * not exist, then assume we have AFS client admin privileges.
1051 PSID psidAdmin
= NULL
;
1052 DWORD dwSize
, dwSize2
;
1053 TCHAR pszAdminGroup
[ MAX_COMPUTERNAME_LENGTH
+ sizeof(AFSCLIENT_ADMIN_GROUPNAME
) + 2 ];
1054 TCHAR
*pszRefDomain
= NULL
;
1055 SID_NAME_USE snu
= SidTypeGroup
;
1057 dwSize
= sizeof(pszAdminGroup
);
1059 if (!GetComputerName(pszAdminGroup
, &dwSize
)) {
1060 /* Can't get computer name. We return false in this case.
1061 Retain fAdmin and fTested. This shouldn't happen.*/
1068 lstrcat(pszAdminGroup
, _T("\\"));
1069 lstrcat(pszAdminGroup
, _T(AFSCLIENT_ADMIN_GROUPNAME
));
1071 LookupAccountName(NULL
, pszAdminGroup
, NULL
, &dwSize
, NULL
, &dwSize2
, &snu
);
1072 /* that should always fail. */
1074 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
) {
1075 /* if we can't find the group, then we allow the operation */
1080 if (dwSize
== 0 || dwSize2
== 0) {
1086 psidAdmin
= (PSID
)malloc(dwSize
); memset(psidAdmin
,0,dwSize
);
1087 pszRefDomain
= (TCHAR
*)malloc(dwSize2
);
1089 if (!LookupAccountName(NULL
, pszAdminGroup
, psidAdmin
, &dwSize
, pszRefDomain
, &dwSize2
, &snu
)) {
1090 /* We can't lookup the group now even though we looked it up earlier.
1091 Could this happen? */
1094 /* Then open our current ProcessToken */
1097 if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY
, &hToken
))
1100 if (!CheckTokenMembership(hToken
, psidAdmin
, &fAdmin
)) {
1101 /* We'll have to allocate a chunk of memory to store the list of
1102 * groups to which this user belongs; find out how much memory
1106 PTOKEN_GROUPS pGroups
;
1108 GetTokenInformation (hToken
, TokenGroups
, NULL
, dwSize
, &dwSize
);
1110 pGroups
= (PTOKEN_GROUPS
)malloc(dwSize
);
1112 /* Allocate that buffer, and read in the list of groups. */
1113 if (GetTokenInformation (hToken
, TokenGroups
, pGroups
, dwSize
, &dwSize
))
1115 /* Look through the list of group SIDs and see if any of them
1116 * matches the AFS Client Admin group SID.
1119 for (; (!fAdmin
) && (iGroup
< pGroups
->GroupCount
); ++iGroup
)
1121 if (EqualSid (psidAdmin
, pGroups
->Groups
[ iGroup
].Sid
)) {
1131 /* if do not have permission because we were not explicitly listed
1132 * in the Admin Client Group let's see if we are the SYSTEM account
1135 PTOKEN_USER pTokenUser
;
1136 SID_IDENTIFIER_AUTHORITY SIDAuth
= SECURITY_NT_AUTHORITY
;
1137 PSID pSidLocalSystem
= 0;
1140 GetTokenInformation(hToken
, TokenUser
, NULL
, 0, &dwSize
);
1142 pTokenUser
= (PTOKEN_USER
)malloc(dwSize
);
1144 if (!GetTokenInformation(hToken
, TokenUser
, pTokenUser
, dwSize
, &dwSize
))
1145 gle
= GetLastError();
1147 if (AllocateAndInitializeSid( &SIDAuth
, 1,
1148 SECURITY_LOCAL_SYSTEM_RID
,
1149 0, 0, 0, 0, 0, 0, 0,
1152 if (EqualSid(pTokenUser
->User
.Sid
, pSidLocalSystem
)) {
1156 FreeSid(pSidLocalSystem
);
1175 Parent(const CString
& path
)
1177 int last_slash
= path
.ReverseFind(_T('\\'));
1179 if (last_slash
!= -1) {
1180 CString ret
= path
.Left(last_slash
+ 1);
1183 if (path
.GetLength() >= 2 && path
[1] == _T(':')) {
1184 CString ret
= path
.Left(2);
1185 ret
.AppendChar(_T('.'));
1188 CString ret
= _T(".");
1195 LastComponent(const CString
& path
)
1197 int last_slash
= path
.ReverseFind(_T('\\'));
1199 if (last_slash
!= -1) {
1200 CString ret
= path
.Mid(last_slash
+ 1);
1203 if (path
.GetLength() >= 2 && path
[1] == _T(':')) {
1204 CString ret
= path
.Mid(2);
1214 GetCell(const CString
& path
, BOOL bFollow
= TRUE
);
1217 GetCell(const CString
& path
, BOOL bFollow
)
1219 char cellname
[MAXCELLCHARS
];
1221 struct ViceIoctl blob
;
1224 blob
.out_size
= sizeof(cellname
);
1225 blob
.out
= cellname
;
1227 code
= pioctl_T(path
, VIOC_FILE_CELL_NAME
, &blob
, 1);
1234 return Utf8ToCString(cellname
);
1240 ListMount(CStringArray
& files
)
1243 struct ViceIoctl blob
;
1246 CString parent_dir
; /* Parent directory of true name */
1247 CStringUtf8 last_component
; /* Last component of true name */
1249 CStringArray mountPoints
;
1251 HOURGLASS hourglass
;
1255 for (int i
= 0; i
< files
.GetSize(); i
++) {
1256 int last_slash
= files
[i
].ReverseFind(_T('\\'));
1257 char space
[AFS_PIOCTL_MAXSIZE
];
1259 if (last_slash
!= -1) {
1260 last_component
.SetString( files
[i
].Mid(last_slash
+ 1) );
1261 parent_dir
.SetString( files
[i
].Left(last_slash
+ 1) );
1262 FixNetbiosPath(parent_dir
);
1264 // The path is of the form "C:foo" or just "foo". If
1265 // there is a drive, then use the current directory of
1266 // that drive. Otherwise we just use '.'.
1268 if (files
[i
].GetLength() >= 2 && files
[i
][1] == _T(':')) {
1269 parent_dir
.Format(_T("%c:."), files
[i
][0]);
1270 last_component
.SetString( files
[i
].Mid(2) );
1272 parent_dir
.SetString( _T("."));
1273 last_component
.SetString( files
[i
] );
1277 blob
.in_size
= last_component
.GetLength() + 1;
1278 blob
.in
= last_component
.GetBuffer();
1279 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
1281 memset(space
, 0, AFS_PIOCTL_MAXSIZE
);
1283 code
= pioctl_T(parent_dir
, VIOC_AFS_STAT_MT_PT
, &blob
, 1);
1285 last_component
.ReleaseBuffer();
1289 space
[AFS_PIOCTL_MAXSIZE
- 1] = '\0';
1290 nPos
= strlen(space
) - 1;
1291 if (space
[nPos
] == '.')
1293 mountPoints
.Add(ParseMountPoint(StripPath(files
[i
]), Utf8ToCString(space
)));
1296 if (errno
== EINVAL
)
1297 mountPoints
.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR
, StripPath(files
[i
])));
1299 mountPoints
.Add(GetMessageString(IDS_LIST_MOUNT_POINT_ERROR
, GetAfsError(errno
, StripPath(files
[i
]))));
1303 CMountPointsDlg dlg
;
1304 dlg
.SetMountPoints(mountPoints
);
1311 MakeMount(const CString
& strDir
,
1312 const CString
& strVolName
,
1313 const CString
& strInCellName
,
1317 struct ViceIoctl blob
;
1318 HOURGLASS hourglass
;
1320 ASSERT(strVolName
.GetLength() < 64);
1322 CString strParent
= Parent(strDir
);
1324 FixNetbiosPath(strParent
);
1325 if (!IsPathInAfs(strParent
)) {
1326 ShowMessageBox(IDS_MAKE_MP_NOT_AFS_ERROR
, MB_ICONERROR
, IDS_MAKE_MP_NOT_AFS_ERROR
);
1330 CString strPath
= strParent
+ LastComponent(strDir
);
1332 if ( IsFreelanceRoot(strParent
) && !IsAdmin() ) {
1333 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR
, MB_ICONERROR
,
1334 IDS_NOT_AFS_CLIENT_ADMIN_ERROR
);
1340 strMount
.Format(_T("%c%s%s%s."),
1341 ((bRW
)?_T('%'):_T('#')),
1343 ((strInCellName
.IsEmpty())?_T(""):_T(":")),
1346 CStringUtf8
ustrMount(strMount
);
1349 blob
.in_size
= ustrMount
.GetLength() + 1;
1350 blob
.in
= ustrMount
.GetBuffer();
1353 code
= pioctl_T(strPath
, VIOC_AFS_CREATE_MT_PT
, &blob
, 0);
1355 ustrMount
.ReleaseBuffer();
1358 ShowMessageBox(IDS_MOUNT_POINT_ERROR
, MB_ICONERROR
, IDS_MOUNT_POINT_ERROR
, GetAfsError(errno
, strDir
));
1366 RemoveSymlink(const CString
& strName
)
1370 struct ViceIoctl blob
;
1371 char lsbuffer
[1024];
1373 HOURGLASS hourglass
;
1375 CString strParent
= Parent(strName
);
1376 CStringUtf8
ustrLast(LastComponent(strName
));
1377 FixNetbiosPath(strParent
);
1379 if ( IsFreelanceRoot(strParent
) && !IsAdmin() ) {
1380 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR
, MB_ICONERROR
, IDS_NOT_AFS_CLIENT_ADMIN_ERROR
);
1384 blob
.in_size
= ustrLast
.GetLength() + 1;
1385 blob
.in
= ustrLast
.GetBuffer();
1386 blob
.out
= lsbuffer
;
1387 blob
.out_size
= sizeof(lsbuffer
);
1388 code
= pioctl_T(strParent
, VIOC_LISTSYMLINK
, &blob
, 0);
1389 ustrLast
.ReleaseBuffer();
1393 blob
.in_size
= ustrLast
.GetLength() + 1;
1394 blob
.in
= ustrLast
.GetBuffer();
1396 code
= pioctl_T(strParent
, VIOC_DELSYMLINK
, &blob
, 0);
1398 ustrLast
.ReleaseBuffer();
1404 IsSymlink(const CString
& strName
)
1406 struct ViceIoctl blob
;
1408 char space
[AFS_PIOCTL_MAXSIZE
];
1409 HOURGLASS hourglass
;
1411 CStringUtf8
ustrLast(LastComponent(strName
));
1412 CString strParent
= Parent(strName
);
1414 FixNetbiosPath(strParent
);
1416 blob
.in_size
= ustrLast
.GetLength() + 1;
1417 blob
.in
= ustrLast
.GetBuffer();
1418 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
1420 memset(space
, 0, AFS_PIOCTL_MAXSIZE
);
1422 code
= pioctl_T(strParent
, VIOC_LISTSYMLINK
, &blob
, 1);
1424 ustrLast
.ReleaseBuffer();
1431 IsMountPoint(const CString
& path
)
1434 struct ViceIoctl blob
;
1435 char lsbuffer
[1024];
1437 HOURGLASS hourglass
;
1439 CString parent
= Parent(path
);
1440 FixNetbiosPath(parent
);
1442 CStringUtf8
mountpoint(LastComponent(path
));
1444 blob
.in_size
= mountpoint
.GetLength() + 1;
1445 blob
.in
= mountpoint
.GetBuffer();
1446 blob
.out
= lsbuffer
;
1447 blob
.out_size
= sizeof(lsbuffer
);
1449 code
= pioctl_T(parent
, VIOC_AFS_STAT_MT_PT
, &blob
, 0);
1451 mountpoint
.ReleaseBuffer();
1458 * Delete AFS mount points. Variables are used as follows:
1459 * tbuffer: Set to point to the null-terminated directory name of the mount point
1460 * (or ``.'' if none is provided)
1461 * tp: Set to point to the actual name of the mount point to nuke.
1464 RemoveMount(CStringArray
& files
)
1467 struct ViceIoctl blob
;
1469 CStringArray results
;
1473 HOURGLASS hourglass
;
1475 for (int i
= 0; i
< files
.GetSize(); i
++) {
1476 if (!IsMountPoint(files
[i
])) {
1478 if (errno
== EINVAL
)
1479 results
.Add(GetMessageString(IDS_NOT_MOUNT_POINT_ERROR
, StripPath(files
[i
])));
1481 results
.Add(GetMessageString(IDS_ERROR
, GetAfsError(errno
, StripPath(files
[i
]))));
1482 continue; // don't bother trying
1485 CString parent
= Parent(files
[i
]);
1486 CStringUtf8
mountpoint(LastComponent(files
[i
]));
1487 FixNetbiosPath(parent
);
1489 if ( IsFreelanceRoot(parent
) && !IsAdmin() ) {
1490 results
.Add(GetMessageString(IDS_NOT_AFS_CLIENT_ADMIN_ERROR
, StripPath(files
[i
])));
1492 continue; /* skip */
1496 blob
.in_size
= mountpoint
.GetLength() + 1;
1497 blob
.in
= mountpoint
.GetBuffer();
1499 code
= pioctl_T(parent
, VIOC_AFS_DELETE_MT_PT
, &blob
, 0);
1501 mountpoint
.ReleaseBuffer();
1505 results
.Add(GetMessageString(IDS_ERROR
, GetAfsError(errno
, StripPath(files
[i
]))));
1507 results
.Add(GetMessageString(IDS_DELETED
));
1510 LoadString (str
, IDS_REMOVE_MP
);
1511 LoadString (str2
, IDS_REMOVE_MP_COLUMN
);
1512 CResultsDlg
dlg(REMOVE_MOUNT_POINTS_HELP_ID
);
1513 dlg
.SetContents(str
, str2
, StripPath(files
), results
);
1520 GetVolumeInfo(CString strFile
, CVolInfo
& volInfo
, BOOL bFollow
)
1523 struct ViceIoctl blob
;
1524 struct VolumeStatus
*status
;
1526 char space
[AFS_PIOCTL_MAXSIZE
];
1527 HOURGLASS hourglass
;
1528 CString strTarget
= bFollow
? strFile
: Parent(strFile
);
1530 volInfo
.m_strFilePath
= strTarget
;
1531 volInfo
.m_strFileName
= StripPath(strTarget
);
1534 volInfo.m_strName = "VolumeName";
1536 volInfo.m_nQuota = 20 * 1024 * 1024;
1537 volInfo.m_nNewQuota = volInfo.m_nQuota;
1538 volInfo.m_nUsed = volInfo.m_nQuota / 2;
1539 volInfo.m_nPartSize = 50 * 1024 * 1024;
1540 volInfo.m_nPartFree = 30 * 1024 * 1024;
1541 volInfo.m_nDup = -1;
1545 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
1549 code
= pioctl_T(strTarget
, VIOCGETVOLSTAT
, &blob
, 1);
1550 if (code
|| blob
.out_size
< sizeof(*status
)) {
1551 volInfo
.m_strErrorMsg
= GetAfsError(errno
, strTarget
);
1555 status
= (VolumeStatus
*)space
;
1556 name
= (char *)status
+ sizeof(*status
);
1558 volInfo
.m_strName
= Utf8ToCString(name
);
1559 volInfo
.m_nID
= status
->Vid
;
1560 volInfo
.m_nQuota
= status
->MaxQuota
;
1561 volInfo
.m_nNewQuota
= status
->MaxQuota
;
1562 volInfo
.m_nUsed
= status
->BlocksInUse
;
1563 volInfo
.m_nPartSize
= status
->PartMaxBlocks
;
1564 volInfo
.m_nPartFree
= status
->PartBlocksAvail
;
1565 volInfo
.m_nDup
= -1;
1568 code
= pioctl_T(strTarget
, VIOC_PATH_AVAILABILITY
, &blob
, 1);
1571 volInfo
.m_strAvail
=_T("Online");
1574 volInfo
.m_strAvail
= _T("Offline");
1577 volInfo
.m_strAvail
= _T("Unreachable");
1580 volInfo
.m_strAvail
= _T("Busy");
1583 volInfo
.m_strAvail
= _T("Unknown");
1590 SetVolInfo(CVolInfo
& volInfo
)
1593 struct ViceIoctl blob
;
1594 struct VolumeStatus
*status
;
1596 char space
[AFS_PIOCTL_MAXSIZE
];
1597 HOURGLASS hourglass
;
1599 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
1600 blob
.in_size
= sizeof(*status
) + 3; /* for the three terminating nulls */
1604 status
= (VolumeStatus
*)space
;
1605 status
->MinQuota
= -1;
1606 status
->MaxQuota
= volInfo
.m_nNewQuota
;
1608 input
= (char *)status
+ sizeof(*status
);
1609 *(input
++) = '\0'; /* never set name: this call doesn't change vldb */
1610 *(input
++) = '\0'; // No offmsg
1611 *(input
++) = '\0'; // No motd
1614 FILE *fp
= OpenFile(szLogFileName
, "a");
1616 fprintf(fp
, "\nSetVolInfo() pioctl parms:\n");
1617 fprintf(fp
, "\tpathp = %s\n\topcode = VIOCSETVOLSTAT (%d)\n\tblobp = %ld\n", PCCHAR(volInfo
.m_strFilePath
), VIOCSETVOLSTAT
, &blob
);
1618 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
);
1619 fprintf(fp
, "\t\t\tstatus->MinQuota = %ld\n", status
->MinQuota
);
1620 fprintf(fp
, "\t\t\tstatus->MaxQuota = %ld\n", status
->MaxQuota
);
1621 fprintf(fp
, "\t\t\tOther status fields aren't set\n");
1622 fprintf(fp
, "\t\t\t3 nulls follow the VolumeStatus structure.\n");
1623 fprintf(fp
, "\tfollow = 1\n");
1628 code
= pioctl_T(volInfo
.m_strFilePath
, VIOCSETVOLSTAT
, &blob
, 1);
1629 if (code
|| blob
.out_size
< sizeof(*status
)) {
1630 ShowMessageBox(IDS_SET_QUOTA_ERROR
, MB_ICONERROR
, IDS_SET_QUOTA_ERROR
, GetAfsError(errno
, volInfo
.m_strName
));
1638 GetCellName(const CString
& cellNamep
, struct afsconf_cell
*infop
)
1640 CStringUtf8
uCellName(cellNamep
);
1642 StringCbCopyA(infop
->name
, sizeof(infop
->name
), uCellName
);
1646 CheckServers(const CString
& strCellName
, WHICH_CELLS nCellsToCheck
, BOOL bFast
)
1649 struct ViceIoctl blob
;
1652 struct afsconf_cell info
;
1653 struct chservinfo checkserv
;
1654 char space
[AFS_PIOCTL_MAXSIZE
];
1655 HOURGLASS hourglass
;
1657 memset(&checkserv
, 0, sizeof(struct chservinfo
));
1658 blob
.in_size
= sizeof(struct chservinfo
);
1659 blob
.in
= (caddr_t
)&checkserv
;
1661 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
1663 memset(space
, 0, sizeof(afs_int32
)); /* so we assure zero when nothing is copied back */
1665 if (nCellsToCheck
== SPECIFIC_CELL
) {
1667 GetCellName(strCellName
, &info
);
1668 strcpy(checkserv
.tbuffer
,info
.name
);
1669 checkserv
.tsize
= strlen(info
.name
) + 1;
1671 if (nCellsToCheck
!= ALL_CELLS
)
1673 strcpy(checkserv
.tbuffer
, "\0");
1674 checkserv
.tsize
= 0;
1677 temp
|= 1; /* set fast flag */
1679 checkserv
.magic
= 0x12345678; /* XXX */
1680 checkserv
.tflags
= temp
;
1681 checkserv
.tinterval
= -1; /* don't change current interval */
1683 code
= pioctl_utf8(0, VIOCCKSERV
, &blob
, 1);
1685 ShowMessageBox(IDS_CHECK_SERVERS_ERROR
, MB_ICONERROR
, IDS_CHECK_SERVERS_ERROR
, GetAfsError(errno
, CString()));
1689 memcpy(&temp
, space
, sizeof(LONG
));
1692 ShowMessageBox(IDS_ALL_SERVERS_RUNNING
, MB_OK
|MB_ICONINFORMATION
, IDS_ALL_SERVERS_RUNNING
);
1696 CStringArray servers
;
1697 for (j
= 0; j
< AFS_MAXHOSTS
; j
++) {
1698 memcpy(&temp
, space
+ j
* sizeof(LONG
), sizeof(LONG
));
1702 char *name
= hostutil_GetNameByINet(temp
);
1706 CDownServersDlg dlg
;
1707 dlg
.SetServerNames(servers
);
1714 GetTokenInfo(CStringArray
& tokenInfo
)
1718 time_t current_time
;
1719 time_t tokenExpireTime
;
1723 struct ktc_principal serviceName
, clientName
;
1724 struct ktc_token token
;
1726 CString strTokenInfo
;
1727 CString strUserName
;
1728 CString strCellName
;
1731 // tokenInfo.Add("");
1735 HOURGLASS hourglass
;
1737 // printf("\nTokens held by the Cache Manager:\n\n");
1739 current_time
= time(0);
1742 rc
= ktc_ListTokens(cellNum
, &cellNum
, &serviceName
);
1743 if (rc
== KTC_NOENT
) {
1745 // printf(" --End of list --\n");
1748 else if (rc
== KTC_NOCM
) {
1749 ShowMessageBox(IDS_GET_TOKENS_NO_AFS_SERVICE
);
1750 // printf("AFS service may not have started\n");
1754 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR
, MB_ICONERROR
, IDS_GET_TOKENS_UNEXPECTED_ERROR
, rc
);
1756 // printf("Unexpected error, code %d\n", rc);
1760 rc
= ktc_GetToken(&serviceName
, &token
, sizeof(token
), &clientName
);
1762 ShowMessageBox(IDS_GET_TOKENS_UNEXPECTED_ERROR2
, MB_ICONERROR
, IDS_GET_TOKENS_UNEXPECTED_ERROR2
,
1763 serviceName
.name
, serviceName
.instance
, serviceName
.cell
, rc
);
1767 tokenExpireTime
= token
.endTime
;
1769 strcpy(userName
, clientName
.name
);
1770 if (clientName
.instance
[0] != 0) {
1771 strcat(userName
, ".");
1772 strcat(userName
, clientName
.instance
);
1775 BOOL bShowName
= FALSE
;
1777 if (userName
[0] == '\0')
1778 ; //printf("Tokens");
1779 // AFS ID is not returned at this time.
1780 // else if (strncmp(userName, "AFS ID", 6) == 0)
1781 // printf("User's (%s) tokens", userName);
1782 // sscanf(userName, "(AFS ID %s)", szAfsID);
1783 else if (strncmp(userName
, "Unix UID", 8) == 0)
1784 ; //printf("Tokens");
1786 strUserName
= userName
;
1787 // printf("User %s's tokens", userName);
1789 // printf(" for %s%s%s@%s ", serviceName.name, serviceName.instance[0] ? "." : "", serviceName.instance, serviceName.cell);
1790 strCellName
= serviceName
.cell
;
1792 if (tokenExpireTime
<= current_time
)
1793 strExpir
= "[>> Expired <<]";
1794 // printf("[>> Expired <<]\n");
1796 expireString
= ctime(&tokenExpireTime
);
1797 expireString
+= 4; /* Skip day of week */
1798 expireString
[12] = '\0'; /* Omit secs & year */
1799 // printf("[Expires %s]\n", expireString);
1801 strExpir
.Format(_T("%S"), expireString
);
1803 strExpir
.Format(_T("%s"), expireString
);
1807 strTokenInfo
= strUserName
+ "\t" + strCellName
+ "\t" + strExpir
+ "\t" + strCellName
;
1808 tokenInfo
.Add(strTokenInfo
);
1812 // printf("Press <Enter> or <Return> when finished: ");
1818 MakeSymbolicLink(const CString
& strName
, const CString
& strTarget
)
1820 struct ViceIoctl blob
;
1822 HOURGLASS hourglass
;
1824 CString strParent
= Parent(strName
);
1825 FixNetbiosPath(strParent
);
1827 if (!IsPathInAfs(strParent
)) {
1828 ShowMessageBox(IDS_MAKE_LNK_NOT_AFS_ERROR
, MB_ICONERROR
, IDS_MAKE_MP_NOT_AFS_ERROR
);
1832 if ( IsFreelanceRoot(strParent
) && !IsAdmin() ) {
1833 ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR
, MB_ICONERROR
, IDS_NOT_AFS_CLIENT_ADMIN_ERROR
);
1837 CStringUtf8
ustrTarget(strTarget
);
1839 blob
.in_size
= ustrTarget
.GetLength() + 1;
1840 blob
.in
= ustrTarget
.GetBuffer();
1844 code
= pioctl_T(strName
, VIOC_SYMLINK
, &blob
, 0);
1846 ustrTarget
.ReleaseBuffer();
1854 ListSymbolicLinkPath(const char *strName
,char *strPath
,UINT nlenPath
)
1856 ASSERT(nlenPath
<MAX_PATH
);
1857 struct ViceIoctl blob
;
1858 char orig_name
[MAX_PATH
+1]; /*Original name, may be modified*/
1859 char true_name
[MAX_PATH
+1]; /*``True'' dirname (e.g., symlink target)*/
1860 char parent_dir
[MAX_PATH
+1]; /*Parent directory of true name*/
1861 char *last_component
; /*Last component of true name*/
1863 char space
[AFS_PIOCTL_MAXSIZE
];
1864 HOURGLASS hourglass
;
1866 strcpy(orig_name
, strName
);
1867 strcpy(true_name
, orig_name
);
1869 * Find rightmost slash, if any.
1871 last_component
= (char *) strrchr(true_name
, '\\');
1872 if (!last_component
)
1873 last_component
= (char *) strrchr(true_name
, '/');
1874 if (last_component
) {
1876 * Found it. Designate everything before it as the parent directory,
1877 * everything after it as the final component.
1879 strncpy(parent_dir
, true_name
, last_component
- true_name
+ 1);
1880 parent_dir
[last_component
- true_name
+ 1] = 0;
1881 last_component
++; /*Skip the slash*/
1883 if (!IsPathInAfs(parent_dir
)) {
1884 const char * nbname
= NetbiosName();
1885 int len
= strlen(nbname
);
1887 if (parent_dir
[0] == '\\' && parent_dir
[1] == '\\' &&
1888 parent_dir
[len
+2] == '\\' &&
1889 parent_dir
[len
+3] == '\0' &&
1890 !strnicmp(nbname
,&parent_dir
[2],len
))
1892 sprintf(parent_dir
,"\\\\%s\\all\\", nbname
);
1898 * No slash appears in the given file name. Set parent_dir to the current
1899 * directory, and the last component as the given name.
1901 fs_ExtractDriveLetter(true_name
, parent_dir
);
1902 strcat(parent_dir
, ".");
1903 last_component
= true_name
;
1904 fs_StripDriveLetter(true_name
, true_name
, sizeof(true_name
));
1906 blob
.in
= last_component
;
1907 blob
.in_size
= strlen(last_component
)+1;
1908 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
1910 memset(space
, 0, AFS_PIOCTL_MAXSIZE
);
1911 if ((code
= pioctl(parent_dir
, VIOC_LISTSYMLINK
, &blob
, 1)))
1912 strcpy(space
,"???");
1913 ASSERT(strlen(space
)<MAX_PATH
);
1914 strncpy(strPath
,space
,nlenPath
);
1918 ListSymlink(CStringArray
& files
)
1921 struct ViceIoctl blob
;
1923 CStringArray symlinks
;
1924 char space
[AFS_PIOCTL_MAXSIZE
];
1925 HOURGLASS hourglass
;
1929 for (int i
= 0; i
< files
.GetSize(); i
++) {
1931 CString strParent
= Parent(files
[i
]);
1932 CStringUtf8
ustrLast(LastComponent(files
[i
]));
1934 FixNetbiosPath(strParent
);
1936 blob
.in_size
= ustrLast
.GetLength() + 1;
1937 blob
.in
= ustrLast
.GetBuffer();
1938 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
1940 memset(space
, 0, AFS_PIOCTL_MAXSIZE
);
1942 code
= pioctl_T(strParent
, VIOC_LISTSYMLINK
, &blob
, 1);
1944 ustrLast
.ReleaseBuffer();
1950 space
[AFS_PIOCTL_MAXSIZE
- 1] = '\0';
1951 syml
= Utf8ToCString(space
);
1952 len
= syml
.GetLength();
1955 if (syml
[len
- 1] == _T('.'))
1956 syml
.Truncate(len
- 1);
1959 symlinks
.Add(ParseSymlink(StripPath(files
[i
]), syml
));
1963 if (errno
== EINVAL
)
1964 symlinks
.Add(GetMessageString(IDS_NOT_SYMLINK_ERROR
, StripPath(files
[i
])));
1966 symlinks
.Add(GetMessageString(IDS_LIST_MOUNT_POINT_ERROR
, GetAfsError(errno
, StripPath(files
[i
]))));
1971 dlg
.SetSymlinks(symlinks
);
1978 GetCellName( const CString
& strPath
, BOOL bFollow
)
1980 return GetCell(bFollow
? strPath
: Parent(strPath
));
1984 GetServer( const CString
& strPath
, BOOL bFollow
)
1987 struct ViceIoctl blob
;
1989 char space
[AFS_PIOCTL_MAXSIZE
];
1991 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
1994 memset(space
, 0, sizeof(space
));
1996 code
= pioctl_T(bFollow
? strPath
: Parent(strPath
), VIOCWHEREIS
, &blob
, 1);
1998 server
=GetAfsError(errno
);
2000 LONG
*hosts
= (LONG
*)space
;
2002 for (int j
= 0; j
< AFS_MAXHOSTS
; j
++) {
2005 char *hostName
= hostutil_GetNameByINet(hosts
[j
]);
2014 GetServers( const CString
& strPath
, CStringArray
& servers
, BOOL bFollow
)
2017 struct ViceIoctl blob
;
2018 char space
[AFS_PIOCTL_MAXSIZE
];
2020 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
2023 memset(space
, 0, sizeof(space
));
2025 code
= pioctl_T(bFollow
? strPath
: Parent(strPath
), VIOCWHEREIS
, &blob
, 1);
2027 servers
.Add(GetAfsError(errno
));
2029 LONG
*hosts
= (LONG
*)space
;
2031 for (int j
= 0; j
< AFS_MAXHOSTS
; j
++) {
2034 char *hostName
= hostutil_GetNameByINet(hosts
[j
]);
2035 servers
.Add(hostName
);
2041 GetOwner( const CString
& strPath
, BOOL bFollow
)
2044 struct ViceIoctl blob
;
2046 CString ret
= TEXT("(unknown)");
2049 blob
.out_size
= 2 * sizeof(afs_int32
);
2050 blob
.out
= (char *) &owner
;
2052 code
= pioctl_T(bFollow
? strPath
: Parent(strPath
), VIOCGETOWNER
, &blob
, 1);
2053 if (code
== 0 && blob
.out_size
== 2 * sizeof(afs_int32
)) {
2054 char oname
[PR_MAXNAMELEN
] = "(unknown)";
2058 cell
= GetCell(strPath
, bFollow
);
2060 /* Go to the PRDB and see if this all number username is valid */
2061 cm_GetConfigDir(confDir
, sizeof(confDir
));
2063 pr_Initialize(1, confDir
, PCCHAR(cell
));
2064 pr_SIdToName(owner
[0], oname
);
2067 ret
.Format(TEXT("%s [%d]"), (LPCTSTR
)CString(oname
), owner
[0]);
2074 GetGroup( const CString
& strPath
, BOOL bFollow
)
2077 struct ViceIoctl blob
;
2079 CString ret
= TEXT("(unknown)");
2082 blob
.out_size
= 2 * sizeof(afs_int32
);
2083 blob
.out
= (char *) &owner
;
2085 code
= pioctl_T(bFollow
? strPath
: Parent(strPath
), VIOCGETOWNER
, &blob
, 1);
2086 if (code
== 0 && blob
.out_size
== 2 * sizeof(afs_int32
)) {
2087 char gname
[PR_MAXNAMELEN
] = "(unknown)";
2091 cell
= GetCell(strPath
, bFollow
);
2093 /* Go to the PRDB and see if this all number username is valid */
2094 cm_GetConfigDir(confDir
, sizeof(confDir
));
2096 pr_Initialize(1, confDir
, PCCHAR(cell
));
2097 pr_SIdToName(owner
[1], gname
);
2100 ret
.Format(TEXT("%s [%d]"), (LPCTSTR
)CString(gname
), owner
[1]);
2107 GetUnixModeBits( const CString
& strPath
, CString
& user
, CString
& group
, CString
& other
, CString
& suid
)
2109 // the strings must match the unix ls command output: "rwx" means read/write/execute permissions
2112 struct ViceIoctl blob
;
2113 afs_uint32 unixModeBits
;
2114 CString ret
= TEXT("(unknown)");
2122 blob
.out_size
= sizeof(afs_int32
);
2123 blob
.out
= (char *) &unixModeBits
;
2125 code
= pioctl_T(strPath
, VIOC_GETUNIXMODE
, &blob
, 1);
2126 if (code
== 0 && blob
.out_size
== sizeof(afs_uint32
)) {
2127 if (unixModeBits
& S_IRUSR
)
2129 if (unixModeBits
& S_IWUSR
)
2131 if (unixModeBits
& S_IXUSR
)
2134 if (unixModeBits
& S_IRGRP
)
2136 if (unixModeBits
& S_IWGRP
)
2138 if (unixModeBits
& S_IXGRP
)
2141 if (unixModeBits
& S_IROTH
)
2143 if (unixModeBits
& S_IWOTH
)
2145 if (unixModeBits
& S_IXOTH
)
2148 if (unixModeBits
& S_ISUID
)
2150 if (unixModeBits
& S_ISGID
)
2152 if (unixModeBits
& S_ISVTX
)
2162 SetUnixModeBits( const CStringArray
& files
, const CString
& user
, const CString
& group
, const CString
& other
, const CString
& suid
)
2164 // set the unix file attributes for all paths in 'files'.
2166 struct ViceIoctl blob
;
2168 cm_ioctlQueryOptions_t options
;
2169 afs_uint32 unixModeBits
;
2172 memset(&inData
, 0, sizeof(inData
));
2173 inData
.options
.size
= sizeof(inData
.options
);
2174 inData
.options
.field_flags
= 0;
2175 inData
.options
.literal
= 0; /* always applying to target */
2176 blob
.in_size
= sizeof(inData
); /* no variable length data */
2180 inData
.unixModeBits
= 0;
2182 if (user
.Find(_T('r')) != -1)
2183 inData
.unixModeBits
|= S_IRUSR
;
2184 if (user
.Find(_T('w')) != -1)
2185 inData
.unixModeBits
|= S_IWUSR
;
2186 if (user
.Find(_T('x')) != -1)
2187 inData
.unixModeBits
|= S_IXUSR
;
2189 if (group
.Find(_T('r')) != -1)
2190 inData
.unixModeBits
|= S_IRGRP
;
2191 if (group
.Find(_T('w')) != -1)
2192 inData
.unixModeBits
|= S_IWGRP
;
2193 if (group
.Find(_T('x')) != -1)
2194 inData
.unixModeBits
|= S_IXGRP
;
2196 if (other
.Find(_T('r')) != -1)
2197 inData
.unixModeBits
|= S_IROTH
;
2198 if (other
.Find(_T('w')) != -1)
2199 inData
.unixModeBits
|= S_IWOTH
;
2200 if (other
.Find(_T('x')) != -1)
2201 inData
.unixModeBits
|= S_IXOTH
;
2203 if (suid
.Find(_T('s')) != -1)
2204 inData
.unixModeBits
|= S_ISUID
;
2205 if (suid
.Find(_T('g')) != -1)
2206 inData
.unixModeBits
|= S_ISGID
;
2207 if (suid
.Find(_T('v')) != -1)
2208 inData
.unixModeBits
|= S_ISVTX
;
2210 for (int i
= 0; i
< files
.GetSize(); i
++)
2211 code
= pioctl_T(files
[i
], VIOC_SETUNIXMODE
, &blob
, 1);
2214 CString
GetMountpoint( const CString
& strPath
)
2217 struct ViceIoctl blob
;
2218 char space
[AFS_PIOCTL_MAXSIZE
];
2219 CString parent_dir
; /* Parent directory of true name */
2220 CStringUtf8 last_component
; /* Last component of true name */
2225 int last_slash
= strPath
.ReverseFind(_T('\\'));
2227 if (last_slash
!= -1) {
2228 last_component
.SetString( strPath
.Mid(last_slash
+ 1) );
2229 parent_dir
.SetString( strPath
.Left(last_slash
+ 1) );
2230 FixNetbiosPath(parent_dir
);
2232 // The path is of the form "C:foo" or just "foo". If
2233 // there is a drive, then use the current directory of
2234 // that drive. Otherwise we just use '.'.
2236 if (strPath
.GetLength() >= 2 && strPath
[1] == _T(':')) {
2237 parent_dir
.Format(_T("%c:."), strPath
[0]);
2238 last_component
.SetString( strPath
.Mid(2) );
2240 parent_dir
.SetString( _T("."));
2241 last_component
.SetString( strPath
);
2245 blob
.in_size
= last_component
.GetLength() + 1;
2246 blob
.in
= last_component
.GetBuffer();
2247 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
2249 memset(space
, 0, AFS_PIOCTL_MAXSIZE
);
2251 code
= pioctl_T(parent_dir
, VIOC_AFS_STAT_MT_PT
, &blob
, 1);
2253 last_component
.ReleaseBuffer();
2257 space
[AFS_PIOCTL_MAXSIZE
- 1] = '\0';
2258 nPos
= strlen(space
) - 1;
2259 if (space
[nPos
] == '.')
2261 mountPoint
= ParseMountPoint(StripPath(strPath
), Utf8ToCString(space
));
2263 if (errno
== EINVAL
)
2264 mountPoint
= GetMessageString(IDS_NOT_MOUNT_POINT_ERROR
, StripPath(strPath
));
2266 mountPoint
= GetMessageString(IDS_LIST_MOUNT_POINT_ERROR
, GetAfsError(errno
, StripPath(strPath
)));
2272 CString
GetSymlink( const CString
& strPath
)
2275 struct ViceIoctl blob
;
2277 char space
[AFS_PIOCTL_MAXSIZE
];
2279 CString strParent
= Parent(strPath
);
2280 CStringUtf8
ustrLast(LastComponent(strPath
));
2282 FixNetbiosPath(strParent
);
2284 blob
.in_size
= ustrLast
.GetLength() + 1;
2285 blob
.in
= ustrLast
.GetBuffer();
2286 blob
.out_size
= AFS_PIOCTL_MAXSIZE
;
2288 memset(space
, 0, AFS_PIOCTL_MAXSIZE
);
2290 code
= pioctl_T(strParent
, VIOC_LISTSYMLINK
, &blob
, 1);
2292 ustrLast
.ReleaseBuffer();
2298 space
[AFS_PIOCTL_MAXSIZE
- 1] = '\0';
2299 syml
= Utf8ToCString(space
);
2300 len
= syml
.GetLength();
2303 if (syml
[len
- 1] == _T('.'))
2304 syml
.Truncate(len
- 1);
2307 symlink
= ParseSymlink(StripPath(strPath
), syml
);
2310 if (errno
== EINVAL
)
2311 symlink
= GetMessageString(IDS_NOT_SYMLINK_ERROR
, StripPath(strPath
));
2313 symlink
= GetMessageString(IDS_LIST_MOUNT_POINT_ERROR
, GetAfsError(errno
, StripPath(strPath
)));