/* * DFS-Perl version 0.35 * * Paul Henson * California State Polytechnic University, Pomona * * Copyright (c) 1997,1998,1999 Paul Henson -- see COPYRIGHT file for details * */ #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef __cplusplus } #endif #undef pthread_getspecific typedef afsFid *DCE__DFS__fid; #define FLSERVER_MAX 5 typedef struct flserver_obj { rpc_binding_handle_t flserver_h[FLSERVER_MAX]; int flserver_h_count; int flserver_h_index; /* VL_GenerateSites */ unsigned32 site_start, site_nextstart; bulkSites site_info; unsigned32 site_count; unsigned32 site_index; /* VL_ListByAttributes */ VldbListByAttributes attributes; bulkentries entry_info; unsigned32 entry_start, entry_nextstart; unsigned32 entry_index; } flserver_obj; typedef flserver_obj *DCE__DFS__flserver; typedef struct ftserver_obj { rpc_binding_handle_t ftserver_h; afsNetAddr addr; /* FTSERVER_ListAggregates */ ftserver_iterator aggr_start, aggr_nextstart; ftserver_aggrEntries aggr_entries; unsigned32 aggr_index; } ftserver_obj; typedef ftserver_obj *DCE__DFS__ftserver; typedef struct aggregate_obj { rpc_binding_handle_t ftserver_h; afsNetAddr addr; unsigned32 id; ftserver_aggrInfo aggr_info; } aggregate_obj; typedef aggregate_obj *DCE__DFS__aggregate; typedef struct fileset_obj { vldbentry entry; unsigned32 rw_mask; unsigned32 bk_mask; unsigned32 ro_mask; unsigned32 vol_id_rw_index; unsigned32 vol_id_ro_index; unsigned32 vol_id_bk_index; int ftserver_rw_index; rpc_binding_handle_t ftserver_h[16]; int ftserver_h_initialized; ftserver_status rw_status; ftserver_status bk_status; ftserver_status ro_status[16]; } fileset_obj; typedef fileset_obj *DCE__DFS__fileset; static error_status_t bind_flservers(char *cell_fs, flserver_obj *flserver) { unsigned32 import_status, group_status, rpc_status; rpc_ns_handle_t import_context; rpc_ns_handle_t group_context; unsigned_char_t *name, *string_binding, *protseq, *network_addr; uuid_t obj_uuid; unsigned_char_t *string_uuid; rpc_binding_handle_t temp_h; rpc_ns_entry_object_inq_begin(rpc_c_ns_syntax_default, cell_fs, &import_context, &import_status); if (import_status) return import_status; rpc_ns_entry_object_inq_next(import_context, &obj_uuid, &import_status); if (import_status) return import_status; rpc_ns_entry_object_inq_done(&import_context, &import_status); uuid_to_string(&obj_uuid, &string_uuid, &import_status); if (import_status) return import_status; rpc_ns_group_mbr_inq_begin(rpc_c_ns_syntax_default, cell_fs, rpc_c_ns_syntax_default, &group_context, &group_status); if (group_status) return group_status; while ((!group_status) && (flserver->flserver_h_count < FLSERVER_MAX)) { rpc_ns_group_mbr_inq_next(group_context, &name, &group_status); if (!group_status) { rpc_ns_binding_import_begin(rpc_c_ns_syntax_default, name, NULL, NULL, &import_context, &import_status); if (import_status) { rpc_ns_binding_import_done(&import_context, &import_status); continue; } rpc_ns_binding_import_next(import_context, &temp_h, &import_status); if (import_status) { rpc_ns_binding_import_done(&import_context, &import_status); continue; } rpc_binding_to_string_binding(temp_h, &string_binding, &import_status); rpc_binding_free(&temp_h, &rpc_status); if (import_status) { rpc_ns_binding_import_done(&import_context, &import_status); continue; } rpc_string_binding_parse(string_binding, NULL, &protseq, &network_addr, NULL, NULL, &import_status); rpc_string_free(&string_binding, &rpc_status); if (import_status) { rpc_ns_binding_import_done(&import_context, &import_status); continue; } rpc_string_binding_compose(string_uuid, protseq, network_addr, NULL, NULL, &string_binding, &import_status); rpc_string_free(&protseq, &rpc_status); rpc_string_free(&network_addr, &rpc_status); if (import_status) { rpc_ns_binding_import_done(&import_context, &import_status); continue; } rpc_binding_from_string_binding(string_binding, &flserver->flserver_h[flserver->flserver_h_count], &import_status); rpc_string_free(&string_binding, &rpc_status); if (!import_status) flserver->flserver_h_count++; rpc_ns_binding_import_done(&import_context, &import_status); } } rpc_ns_group_mbr_inq_done(&group_context, &group_status); rpc_string_free(&string_uuid, &import_status); flserver->flserver_h_index = time(NULL) % flserver->flserver_h_count; return 0; } static error_status_t init_ftserver_h(rpc_binding_handle_t *ftserver_h, afsNetAddr *addr) { unsigned_char_t *string_binding, *s_name; sec_login_handle_t login_context; error_status_t status, status2; rpc_string_binding_compose(NULL, "ncadg_ip_udp", inet_ntoa(((struct sockaddr_in *)(addr))->sin_addr), NULL, NULL, &string_binding, &status); if (status) return status; rpc_binding_from_string_binding(string_binding, ftserver_h, &status); rpc_string_free(&string_binding, &status2); if (status) return status; sec_login_get_current_context(&login_context, &status); if (!status) { rpc_ep_resolve_binding(*ftserver_h, FTSERVER_v4_0_c_ifspec, &status); if (!status) { rpc_mgmt_inq_server_princ_name(*ftserver_h, rpc_c_authn_default, &s_name, &status); if (!status) { rpc_binding_set_auth_info(*ftserver_h, s_name, rpc_c_protect_level_default, rpc_c_authn_default, login_context, rpc_c_authz_dce, &status); rpc_string_free(&s_name, &status); } } } return status; } static error_status_t init_ftserver_state(DCE__DFS__ftserver ftserver) { ftserver->aggr_start.index = ftserver->aggr_nextstart.index = ftserver->aggr_index = 0; ftserver->aggr_entries.ftserver_aggrList_len = 0; return 0; } static error_status_t init_ftserver(DCE__DFS__ftserver ftserver) { error_status_t status; if (status = init_ftserver_h(&ftserver->ftserver_h, &ftserver->addr)) return status; return init_ftserver_state(ftserver); } static error_status_t update_fileset(DCE__DFS__fileset fileset, int ftserver_index, int fileset_type) { error_status_t status = 0; if (ftserver_index < 0 || ftserver_index >= fileset->entry.nServers || fileset_type < 0 || fileset_type > 2) status = REP_ERR_INVAL_PARAM; else { if (!(fileset->ftserver_h_initialized & (1 << ftserver_index))) if (!(status = init_ftserver_h(&fileset->ftserver_h[ftserver_index], &fileset->entry.siteAddr[ftserver_index]))) fileset->ftserver_h_initialized |= (1 << ftserver_index); if (!status) if (fileset_type == 0) status = FTSERVER_GetOneVolStatus(fileset->ftserver_h[ftserver_index], &fileset->entry.VolIDs[fileset->vol_id_rw_index], fileset->entry.sitePartition[ftserver_index], 0, &fileset->rw_status); else if (fileset_type == 1) status = FTSERVER_GetOneVolStatus(fileset->ftserver_h[ftserver_index], &fileset->entry.VolIDs[fileset->vol_id_ro_index], fileset->entry.sitePartition[ftserver_index], 0, &fileset->ro_status[ftserver_index]); else status = FTSERVER_GetOneVolStatus(fileset->ftserver_h[ftserver_index], &fileset->entry.VolIDs[fileset->vol_id_bk_index], fileset->entry.sitePartition[ftserver_index], 0, &fileset->bk_status); } return status; } static int not_here(s) char *s; { croak("%s not implemented on this architecture", s); return -1; } static double constant(name, arg) char *name; int arg; { errno = 0; switch (*name) { } errno = EINVAL; return 0; not_there: errno = ENOENT; return 0; } MODULE = DCE::DFS PACKAGE = DCE::DFS void cellname(path) char *path CODE: struct afs_ioctl ioctl_buf; char cellname[300]; ioctl_buf.in_size = 0; ioctl_buf.out_size = sizeof(cellname); ioctl_buf.out = cellname; if (!pioctl(path, VIOC_FILE_CELL_NAME, &ioctl_buf, 1)) ST(0) = sv_2mortal(newSVpv(cellname, strlen(cellname))); else ST(0) = &PL_sv_undef; int crmount(path, fileset, read_write = 0) char *path char *fileset int read_write CODE: { char ioctl_data[2048+1]; struct afs_ioctl ioctl_buf; struct cm_CreateMountPoint *mountp; char *mount_dir; char *mount_name; char *index; char link[1024+1]; if (index = rindex(path, '/')) { *index = '\0'; mount_dir = path; mount_name = index + 1; } else { mount_dir = "."; mount_name = path; } link[0] = read_write ? '%' : '#'; link[1] = '\0'; strcat(link, fileset); strcat(link, "."); bzero(ioctl_data, sizeof(ioctl_data)); mountp = (struct cm_CreateMountPoint *) ioctl_data; mountp->nameOffset = sizeof(struct cm_CreateMountPoint); mountp->nameLen = strlen(mount_name); mountp->nameTag = 0; mountp->pathOffset = mountp->nameOffset + mountp->nameLen + 1; mountp->pathLen = strlen(link); mountp->pathTag = 0; if ((mountp->pathOffset + mountp->pathLen) <= 2048) { strcpy(&ioctl_data[mountp->nameOffset], mount_name); strcpy(&ioctl_data[mountp->pathOffset], link); ioctl_buf.out_size = 0; ioctl_buf.out = 0; ioctl_buf.in = ioctl_data; ioctl_buf.in_size = mountp->pathOffset + mountp->pathLen + 1; RETVAL = pioctl(mount_dir, VIOC_AFS_CREATE_MT_PT, &ioctl_buf, 1); } else RETVAL = ENOMEM; } OUTPUT: RETVAL int delmount(path) char *path CODE: { struct afs_ioctl ioctl_buf; char *mount_dir; char *mount_name; char *index; index = path + strlen(path) - 1; while ((index >= path) && (*index == '/')) *index-- = '\0'; ioctl_buf.out_size = 0; ioctl_buf.out = 0; if (index = rindex(path, '/')) { *index = '\0'; mount_name = index + 1; mount_dir = path; } else { mount_name = path; mount_dir = "."; } ioctl_buf.in = mount_name; ioctl_buf.in_size = strlen(mount_name) + 1; if (*mount_dir) RETVAL = pioctl(mount_dir, VIOC_AFS_DELETE_MT_PT, &ioctl_buf, 1); else RETVAL = EINVAL; } OUTPUT: RETVAL void fid(path) char *path PPCODE: { struct afs_ioctl ioctl_buf; DCE__DFS__fid fid; error_status_t status = 0; SV *sv = &PL_sv_undef; if (!(fid = (DCE__DFS__fid)malloc(sizeof(struct afsFid)))) status = sec_s_no_memory; else { ioctl_buf.in_size = 0; ioctl_buf.out_size = sizeof(struct afsFid); ioctl_buf.out = (caddr_t) fid; if (!(status = pioctl(path, VIOCGETFID, &ioctl_buf, 1))) { sv = sv_newmortal(); sv_setref_pv(sv, "DCE::DFS::fid", (void*)fid); } else { free(fid); } } XPUSHs(sv); sv = sv_2mortal(newSViv(status)); XPUSHs(sv); } void flserver(cell_fs = "/.:/fs") char *cell_fs PPCODE: { SV *sv; DCE__DFS__flserver flserver; error_status_t status; if (!(flserver = (DCE__DFS__flserver)malloc(sizeof(flserver_obj)))) { sv = &PL_sv_undef; XPUSHs(sv); sv = sv_2mortal(newSViv(sec_s_no_memory)); XPUSHs(sv); } else { flserver->flserver_h_count = 0; flserver->flserver_h_index = 0; flserver->site_start = flserver->site_count = flserver->site_index = 0; flserver->attributes.Mask = 0; flserver->entry_info.bulkentries_len = flserver->entry_start = flserver->entry_nextstart = 0; flserver->entry_index = 0; status = bind_flservers(cell_fs, flserver); if ( (status) || (flserver->flserver_h_count == 0) ) { free(flserver); sv = &PL_sv_undef; XPUSHs(sv); sv = sv_2mortal(newSViv((status) ? (status) : (-1))); XPUSHs(sv); } else { sv = sv_newmortal(); sv_setref_pv(sv,"DCE::DFS::flserver", (void *)flserver); XPUSHs(sv); sv = sv_2mortal(newSViv(0)); XPUSHs(sv); } } } MODULE = DCE::DFS PACKAGE = DCE::DFS::fid void DESTROY(fid) DCE::DFS::fid fid CODE: free((void *)fid); void id(fid) DCE::DFS::fid fid PPCODE: { char buf[32]; sprintf(buf, "%d,,%d", AFS_hgethi(fid->Volume), AFS_hgetlo(fid->Volume)); XPUSHs(sv_2mortal(newSVpv(buf, strlen(buf)))); } MODULE = DCE::DFS PACKAGE = DCE::DFS::flserver void DESTROY(flserver) DCE::DFS::flserver flserver CODE: { int index; unsigned32 status; for (index = 0; index < flserver->flserver_h_count; index++) rpc_binding_free(&flserver->flserver_h[index], &status); free((void *)flserver); } void ftserver_reset(flserver) DCE::DFS::flserver flserver CODE: { flserver->site_start = flserver->site_count = flserver->site_index = 0; } void ftserver(flserver) DCE::DFS::flserver flserver PPCODE: { DCE__DFS__ftserver ftserver; error_status_t status = 0; int index; SV *sv = &PL_sv_undef; if (flserver->site_index >= flserver->site_count) { for(index = 0; index < flserver->flserver_h_count; index++) { error_status_t reset_status; status = VL_GenerateSites(flserver->flserver_h[flserver->flserver_h_index], flserver->site_start, &flserver->site_nextstart, &flserver->site_info, &flserver->site_count); if (!(status >= rpc_s_mod && status <= rpc_s_mod+4096)) break; rpc_binding_reset(flserver->flserver_h[flserver->flserver_h_index], &reset_status); flserver->flserver_h_index = ((flserver->flserver_h_index + 1) % flserver->flserver_h_count); } flserver->site_start = flserver->site_nextstart; flserver->site_index = 0; } if (status) { flserver->site_start = flserver->site_count = flserver->site_index = 0; } else { if (ftserver = (DCE__DFS__ftserver)malloc(sizeof(ftserver_obj))) { ftserver->addr = flserver->site_info.Sites[flserver->site_index].Addr[0]; if (!(status = init_ftserver(ftserver))) { sv = sv_newmortal(); sv_setref_pv(sv,"DCE::DFS::ftserver", (void *)ftserver); } else { free(ftserver); } } else status = sec_s_no_memory; flserver->site_index++; } XPUSHs(sv); XPUSHs(sv_2mortal(newSViv(status))); } void ftserver_by_name(flserver, name) DCE::DFS::flserver flserver char *name PPCODE: { DCE__DFS__ftserver ftserver; error_status_t status; u_long addr = 0; struct hostent *host; SV *sv = &PL_sv_undef; if ((int)(addr = inet_addr(name)) == -1) if (host = gethostbyname(name)) memcpy(&addr, host->h_addr, sizeof(addr)); else addr = 0; if (!addr) status = REP_ERR_INVAL_PARAM; else if (!(ftserver = (DCE__DFS__ftserver)malloc(sizeof(ftserver_obj)))) status = sec_s_no_memory; else { memcpy(&((struct sockaddr_in *)(&ftserver->addr))->sin_addr, &addr, sizeof(((struct sockaddr_in *)(&ftserver->addr))->sin_addr)); if (!(status = init_ftserver(ftserver))) { sv = sv_newmortal(); sv_setref_pv(sv,"DCE::DFS::ftserver", (void *)ftserver); } else free(ftserver); } XPUSHs(sv); XPUSHs(sv_2mortal(newSViv(status))); } void fileset_reset(flserver) DCE::DFS::flserver flserver CODE: { flserver->attributes.Mask = 0; flserver->entry_info.bulkentries_len = flserver->entry_start = flserver->entry_nextstart = 0; flserver->entry_index = 0; } void fileset_mask_ftserver(flserver, ftserver) DCE::DFS::flserver flserver DCE::DFS::ftserver ftserver CODE: { flserver->attributes.site = ftserver->addr; flserver->attributes.Mask |= VLLIST_SITE; } void fileset_mask_aggregate(flserver, aggr) DCE::DFS::flserver flserver DCE::DFS::aggregate aggr CODE: { flserver->attributes.partition = aggr->id; flserver->attributes.Mask |= VLLIST_PARTITION; } void fileset_mask_type(flserver, type) DCE::DFS::flserver flserver int type CODE: { flserver->attributes.volumetype = VOLTIX_TO_VOLTYPE(type); flserver->attributes.Mask |= VLLIST_VOLUMETYPE; } void fileset(flserver) DCE::DFS::flserver flserver PPCODE: { DCE__DFS__fileset fileset; error_status_t status = 0; unsigned32 dummy, dummy2; int index; SV *sv = &PL_sv_undef; if (flserver->entry_index >= flserver->entry_info.bulkentries_len) { for(index = 0; index < flserver->flserver_h_count; index++) { error_status_t reset_status; status = VL_ListByAttributes(flserver->flserver_h[flserver->flserver_h_index], &flserver->attributes, flserver->entry_start, &dummy, &flserver->entry_info, &flserver->entry_nextstart, &dummy2); if (!(status >= rpc_s_mod && status <= rpc_s_mod+4096)) break; rpc_binding_reset(flserver->flserver_h[flserver->flserver_h_index], &reset_status); flserver->flserver_h_index = ((flserver->flserver_h_index + 1) % flserver->flserver_h_count); } flserver->entry_start = flserver->entry_nextstart; flserver->entry_index = 0; } if (status) { flserver->entry_start = flserver->entry_info.bulkentries_len = flserver->entry_index = 0; } else { if (fileset = (DCE__DFS__fileset)malloc(sizeof(fileset_obj))) { fileset->entry = flserver->entry_info.bulkentries_val[flserver->entry_index]; for (index = 0; index < MAXVOLTYPES && !AFS_hiszero(fileset->entry.VolIDs[index]); index++) switch (fileset->entry.VolTypes[index]) { case VOLTIX_TO_VOLTYPE(RWVOL): fileset->rw_mask = ((unsigned32)VLSF_ZEROIXHERE) >> index; fileset->vol_id_rw_index = index; break; case VOLTIX_TO_VOLTYPE(ROVOL): fileset->ro_mask = ((unsigned32)VLSF_ZEROIXHERE) >> index; fileset->vol_id_ro_index = index; break; case VOLTIX_TO_VOLTYPE(BACKVOL): fileset->bk_mask = ((unsigned32)VLSF_ZEROIXHERE) >> index; fileset->vol_id_bk_index = index; break; } for (index = 0; index < fileset->entry.nServers; index++) if (fileset->entry.siteFlags[index] & fileset->rw_mask) fileset->ftserver_rw_index = index; fileset->ftserver_h_initialized = 0; sv = sv_newmortal(); sv_setref_pv(sv,"DCE::DFS::fileset", (void *)fileset); flserver->entry_index++; } else { status = sec_s_no_memory; } } XPUSHs(sv); sv = sv_2mortal(newSViv(status)); XPUSHs(sv); } void fileset_by_name(flserver, name) DCE::DFS::flserver flserver char *name PPCODE: { error_status_t status; DCE__DFS__fileset fileset; SV *sv = &PL_sv_undef; int index; if (fileset = (DCE__DFS__fileset)malloc(sizeof(fileset_obj))) { for(index = 0; index < flserver->flserver_h_count; index++) { error_status_t reset_status; status = VL_GetEntryByName(flserver->flserver_h[flserver->flserver_h_index], name, &fileset->entry); if (!(status >= rpc_s_mod && status <= rpc_s_mod+4096)) break; rpc_binding_reset(flserver->flserver_h[flserver->flserver_h_index], &reset_status); flserver->flserver_h_index = ((flserver->flserver_h_index + 1) % flserver->flserver_h_count); } if (!status) { fileset->ftserver_h_initialized = 0; sv = sv_newmortal(); sv_setref_pv(sv,"DCE::DFS::fileset", (void *)fileset); for (index = 0; index < MAXVOLTYPES && !AFS_hiszero(fileset->entry.VolIDs[index]); index++) switch (fileset->entry.VolTypes[index]) { case VOLTIX_TO_VOLTYPE(RWVOL): fileset->rw_mask = ((unsigned32)VLSF_ZEROIXHERE) >> index; fileset->vol_id_rw_index = index; break; case VOLTIX_TO_VOLTYPE(ROVOL): fileset->ro_mask = ((unsigned32)VLSF_ZEROIXHERE) >> index; fileset->vol_id_ro_index = index; break; case VOLTIX_TO_VOLTYPE(BACKVOL): fileset->bk_mask = ((unsigned32)VLSF_ZEROIXHERE) >> index; fileset->vol_id_bk_index = index; break; } for (index = 0; index < fileset->entry.nServers; index++) if (fileset->entry.siteFlags[index] & fileset->rw_mask) fileset->ftserver_rw_index = index; } else { free(fileset); } } else status = sec_s_no_memory; XPUSHs(sv); sv = sv_2mortal(newSViv(status)); XPUSHs(sv); } void fileset_by_id(flserver, fid) DCE::DFS::flserver flserver DCE::DFS::fid fid PPCODE: { error_status_t status; DCE__DFS__fileset fileset; SV *sv = &PL_sv_undef; int index; if (fileset = (DCE__DFS__fileset)malloc(sizeof(fileset_obj))) { for(index = 0; index < flserver->flserver_h_count; index++) { error_status_t reset_status; status = VL_GetEntryByID(flserver->flserver_h[0], &fid->Volume, -1, &fileset->entry); if (!(status >= rpc_s_mod && status <= rpc_s_mod+4096)) break; rpc_binding_reset(flserver->flserver_h[flserver->flserver_h_index], &reset_status); flserver->flserver_h_index = ((flserver->flserver_h_index + 1) % flserver->flserver_h_count); } if (!status) { fileset->ftserver_h_initialized = 0; sv = sv_newmortal(); sv_setref_pv(sv,"DCE::DFS::fileset", (void *)fileset); for (index = 0; index < MAXVOLTYPES && !AFS_hiszero(fileset->entry.VolIDs[index]); index++) switch (fileset->entry.VolTypes[index]) { case VOLTIX_TO_VOLTYPE(RWVOL): fileset->rw_mask = ((unsigned32)VLSF_ZEROIXHERE) >> index; fileset->vol_id_rw_index = index; break; case VOLTIX_TO_VOLTYPE(ROVOL): fileset->ro_mask = ((unsigned32)VLSF_ZEROIXHERE) >> index; fileset->vol_id_ro_index = index; break; case VOLTIX_TO_VOLTYPE(BACKVOL): fileset->bk_mask = ((unsigned32)VLSF_ZEROIXHERE) >> index; fileset->vol_id_bk_index = index; break; } for (index = 0; index < fileset->entry.nServers; index++) if (fileset->entry.siteFlags[index] & fileset->rw_mask) fileset->ftserver_rw_index = index; } } else status = sec_s_no_memory; XPUSHs(sv); sv = sv_2mortal(newSViv(status)); XPUSHs(sv); } MODULE = DCE::DFS PACKAGE = DCE::DFS::ftserver void DESTROY(ftserver) DCE::DFS::ftserver ftserver CODE: { unsigned32 status; rpc_binding_free(&ftserver->ftserver_h, &status); free((void *)ftserver); } void address(ftserver) DCE::DFS::ftserver ftserver CODE: { char *address = inet_ntoa(((struct sockaddr_in *)(&ftserver->addr))->sin_addr); if (address) ST(0) = sv_2mortal(newSVpv(address, strlen(address))); else ST(0) = &PL_sv_undef; } void hostname(ftserver) DCE::DFS::ftserver ftserver CODE: { struct hostent *host = gethostbyaddr((const char *)&((struct sockaddr_in *)(&ftserver->addr))->sin_addr, sizeof(((struct sockaddr_in *)(&ftserver->addr))->sin_addr), AF_INET); char *retval; if (host) retval = host->h_name; else retval = inet_ntoa(((struct sockaddr_in *)(&ftserver->addr))->sin_addr); if (retval) ST(0) = sv_2mortal(newSVpv(retval, strlen(retval))); else ST(0) = &PL_sv_undef; } void aggregate(ftserver) DCE::DFS::ftserver ftserver PPCODE: { DCE__DFS__aggregate aggr; error_status_t status = 0; SV *sv = &PL_sv_undef; if (ftserver->aggr_index >= ftserver->aggr_entries.ftserver_aggrList_len) { status = FTSERVER_ListAggregates(ftserver->ftserver_h, &ftserver->aggr_start, &ftserver->aggr_nextstart, &ftserver->aggr_entries); if (ftserver->aggr_start.index == ftserver->aggr_nextstart.index) ftserver->aggr_start.index = ftserver->aggr_nextstart.index = 0; else ftserver->aggr_start = ftserver->aggr_nextstart; ftserver->aggr_index = 0; } if (!status) if (ftserver->aggr_entries.ftserver_aggrList_len > 0) { if (aggr = (DCE__DFS__aggregate)malloc(sizeof(aggregate_obj))) { status = FTSERVER_AggregateInfo(ftserver->ftserver_h, ftserver->aggr_entries.ftserver_aggrEntries_val[ftserver->aggr_index].Id, &aggr->aggr_info); if (!status) { rpc_binding_copy(ftserver->ftserver_h, &aggr->ftserver_h, &status); aggr->addr = ftserver->addr; aggr->id = ftserver->aggr_entries.ftserver_aggrEntries_val[ftserver->aggr_index].Id; sv = sv_newmortal(); sv_setref_pv(sv, "DCE::DFS::aggregate", (void *)aggr); } else { free(aggr); } } else status = sec_s_no_memory; ftserver->aggr_index++; } else status = VL_ENDOFLIST; XPUSHs(sv); XPUSHs(sv_2mortal(newSViv(status))); } MODULE = DCE::DFS PACKAGE = DCE::DFS::aggregate void DESTROY(aggr) DCE::DFS::aggregate aggr CODE: { unsigned32 status; rpc_binding_free(&aggr->ftserver_h, &status); free((void *)aggr); } void ftserver(aggr) DCE::DFS::aggregate aggr PPCODE: { DCE__DFS__ftserver ftserver; error_status_t status = 0; SV *sv = &PL_sv_undef; if (ftserver = (DCE__DFS__ftserver)malloc(sizeof(ftserver_obj))) { ftserver->addr = aggr->addr; rpc_binding_copy(aggr->ftserver_h, &ftserver->ftserver_h, &status); init_ftserver_state(ftserver); sv = sv_newmortal(); sv_setref_pv(sv,"DCE::DFS::ftserver", (void *)ftserver); } else status = sec_s_no_memory; XPUSHs(sv); sv = sv_2mortal(newSViv(status)); XPUSHs(sv); } void name(aggr) DCE::DFS::aggregate aggr CODE: ST(0) = sv_2mortal(newSVpv(aggr->aggr_info.name, strlen(aggr->aggr_info.name))); void device(aggr) DCE::DFS::aggregate aggr CODE: ST(0) = sv_2mortal(newSVpv(aggr->aggr_info.devName, strlen(aggr->aggr_info.devName))); int id(aggr) DCE::DFS::aggregate aggr CODE: RETVAL = aggr->id; OUTPUT: RETVAL int type(aggr) DCE::DFS::aggregate aggr CODE: RETVAL = aggr->aggr_info.type; OUTPUT: RETVAL int size(aggr) DCE::DFS::aggregate aggr CODE: RETVAL = aggr->aggr_info.totalUsable; OUTPUT: RETVAL int free(aggr) DCE::DFS::aggregate aggr CODE: RETVAL = aggr->aggr_info.curFree; OUTPUT: RETVAL MODULE = DCE::DFS PACKAGE = DCE::DFS::fileset void DESTROY(fileset) DCE::DFS::fileset fileset CODE: { unsigned32 status; int index; for (index = 0; index < 16; index++) if (fileset->ftserver_h_initialized & (1 << index)) rpc_binding_free(&fileset->ftserver_h[index], &status); free((void *)fileset); } void ftserver(fileset, ftserver_index = -1) DCE::DFS::fileset fileset int ftserver_index PPCODE: { DCE__DFS__ftserver ftserver; error_status_t status = 0; SV *sv = &PL_sv_undef; int index = ((ftserver_index == -1) ? fileset->ftserver_rw_index : ftserver_index); if (index < 0 || index >= fileset->entry.nServers) status = REP_ERR_INVAL_PARAM; else if (!(ftserver = (DCE__DFS__ftserver)malloc(sizeof(ftserver_obj)))) status = sec_s_no_memory; else { if (!(fileset->ftserver_h_initialized & (1 << index))) if (!(status = init_ftserver_h(&fileset->ftserver_h[index], &fileset->entry.siteAddr[index]))) fileset->ftserver_h_initialized |= (1 << index); if (!status) { ftserver->addr = fileset->entry.siteAddr[index]; rpc_binding_copy(fileset->ftserver_h[index], &ftserver->ftserver_h, &status); init_ftserver_state(ftserver); sv = sv_newmortal(); sv_setref_pv(sv,"DCE::DFS::ftserver", (void *)ftserver); } } XPUSHs(sv); sv = sv_2mortal(newSViv(status)); XPUSHs(sv); } void aggregate(fileset, ftserver_index = -1) DCE::DFS::fileset fileset int ftserver_index PPCODE: { DCE__DFS__aggregate aggr; error_status_t status = 0; int index = ((ftserver_index == -1) ? fileset->ftserver_rw_index : ftserver_index); SV *sv = &PL_sv_undef; if (index < 0 || index >= fileset->entry.nServers) status = REP_ERR_INVAL_PARAM; else if (!(aggr = (DCE__DFS__aggregate)malloc(sizeof(aggregate_obj)))) status = sec_s_no_memory; else { if (!(fileset->ftserver_h_initialized & (1 << index))) if (!(status = init_ftserver_h(&fileset->ftserver_h[index], &fileset->entry.siteAddr[index]))) fileset->ftserver_h_initialized |= (1 << index); if (!status) { status = FTSERVER_AggregateInfo(fileset->ftserver_h[index], fileset->entry.sitePartition[index], &aggr->aggr_info); if (!status) { rpc_binding_copy(fileset->ftserver_h[index], &aggr->ftserver_h, &status); aggr->addr = fileset->entry.siteAddr[index]; aggr->id = fileset->entry.sitePartition[index]; sv = sv_newmortal(); sv_setref_pv(sv, "DCE::DFS::aggregate", (void *)aggr); } } } XPUSHs(sv); sv = sv_2mortal(newSViv(status)); XPUSHs(sv); } void name(fileset) DCE::DFS::fileset fileset CODE: ST(0) = sv_2mortal(newSVpv(fileset->entry.name, strlen(fileset->entry.name))); int ftserver_count(fileset) DCE::DFS::fileset fileset CODE: { RETVAL = fileset->entry.nServers; } OUTPUT: RETVAL int ftserver_index(fileset, ftserver) DCE::DFS::fileset fileset DCE::DFS::ftserver ftserver CODE: { int ftserver_index = -1; int index; for (index = 0; index < fileset->entry.nServers; index++) if (memcmp((void *)&fileset->entry.siteAddr[index], (void *)&ftserver->addr, sizeof(ftserver->addr)) == 0) ftserver_index = index; RETVAL = ftserver_index; } OUTPUT: RETVAL int exists(fileset, fileset_type, ftserver_index = -1) DCE::DFS::fileset fileset int fileset_type int ftserver_index CODE: { int exists = 0; if (ftserver_index == -1) switch (fileset_type) { case 0: exists = fileset->entry.flags & VLF_RWEXISTS; break; case 1: exists = fileset->entry.flags & VLF_ROEXISTS; break; case 2: exists = fileset->entry.flags & VLF_BACKEXISTS; break; } else if (ftserver_index >= 0 && ftserver_index < fileset->entry.nServers) switch (fileset_type) { case 0: exists = fileset->entry.siteFlags[ftserver_index] & fileset->rw_mask; break; case 1: exists = fileset->entry.siteFlags[ftserver_index] & fileset->ro_mask; break; case 2: exists = fileset->entry.siteFlags[ftserver_index] & fileset->bk_mask; break; } RETVAL = exists; } OUTPUT: RETVAL void usage(fileset, ftserver_index = -1, fileset_type = 0) DCE::DFS::fileset fileset int ftserver_index int fileset_type PPCODE: { SV *sv; error_status_t status; int index = ((ftserver_index == -1) ? fileset->ftserver_rw_index : ftserver_index); ftserver_status *ft_status = NULL; unsigned32 seconds, reads, writes; time_t now; status = update_fileset(fileset, index, fileset_type); now = time(NULL); if (!status) { if (index < 0 || index >= fileset->entry.nServers || fileset_type < 0 || fileset_type > 2) status = REP_ERR_INVAL_PARAM; else if (fileset_type == 0) { if (fileset->entry.siteFlags[index] & fileset->rw_mask) ft_status = &fileset->rw_status; } else if (fileset_type == 1) { if (fileset->entry.siteFlags[index] & fileset->ro_mask) ft_status = &fileset->ro_status[index]; } else if (fileset_type == 2) { if (fileset->entry.siteFlags[index] & fileset->bk_mask) ft_status = &fileset->bk_status; } if (!ft_status) status = REP_ERR_INVAL_PARAM; else { seconds = now - ft_status->vss.countInitTime; reads = ft_status->vss.readVnopCount; writes = ft_status->vss.writeVnopCount; } } sv = sv_2mortal(newSViv(seconds)); XPUSHs(sv); sv = sv_2mortal(newSViv(reads)); XPUSHs(sv); sv = sv_2mortal(newSViv(writes)); XPUSHs(sv); sv = sv_2mortal(newSViv(status)); XPUSHs(sv); } void quota(fileset) DCE::DFS::fileset fileset PPCODE: { SV *sv; error_status_t status; unsigned32 quota, used; status = update_fileset(fileset, fileset->ftserver_rw_index, 0); if (!status) { quota = ((0xffc00000 & (AFS_hgethi(fileset->rw_status.vsd.visQuotaLimit) << 22)) | (0x003fffff & (AFS_hgetlo(fileset->rw_status.vsd.visQuotaLimit) >> 10))); used = ((0xffc00000 & (AFS_hgethi(fileset->rw_status.vsd.visQuotaUsage) << 22)) | (0x003fffff & (AFS_hgetlo(fileset->rw_status.vsd.visQuotaUsage) >> 10))); } sv = sv_2mortal(newSViv(quota)); XPUSHs(sv); sv = sv_2mortal(newSViv(used)); XPUSHs(sv); sv = sv_2mortal(newSViv(status)); XPUSHs(sv); } int set_quota(fileset, quota) DCE::DFS::fileset fileset int quota CODE: { struct ftserver_status ft_status; long trans_id; error_status_t status = 0; if (!(fileset->ftserver_h_initialized & (1 << fileset->ftserver_rw_index))) if (!(status = init_ftserver_h(&fileset->ftserver_h[fileset->ftserver_rw_index], &fileset->entry.siteAddr[fileset->ftserver_rw_index]))) fileset->ftserver_h_initialized |= (1 << fileset->ftserver_rw_index); if (!status) if (!(status = FTSERVER_CreateTrans(fileset->ftserver_h[fileset->ftserver_rw_index], &fileset->entry.VolIDs[fileset->vol_id_rw_index], fileset->entry.sitePartition[fileset->ftserver_rw_index], FLAGS_ENCODE(FTSERVER_OP_SETSTATUS, VOLERR_TRANS_SETQUOTA), &trans_id))) { AFS_hset32(ft_status.vsd.visQuotaLimit, quota); AFS_hleftshift(ft_status.vsd.visQuotaLimit, 10); if (status = FTSERVER_SetStatus(fileset->ftserver_h[fileset->ftserver_rw_index], trans_id, VOL_STAT_VISLIMIT, &ft_status, 0)) FTSERVER_AbortTrans(fileset->ftserver_h[fileset->ftserver_rw_index], trans_id); else FTSERVER_DeleteTrans(fileset->ftserver_h[fileset->ftserver_rw_index], trans_id); } RETVAL = status; } OUTPUT: RETVAL