📄 usedir.c
字号:
if (ret != CS_SUCCEED)
{
/*
** Return CS_SUCCEED to discard the rest of the objects
** that were found in the search.
*/
ex_error(
"directory_cb: Too many servers! Truncating search results.");
return CS_SUCCEED;
}
/*
** Return CS_CONTINUE so Client-Library will call us again if more
** entries are found.
*/
return CS_CONTINUE;
} /* directory_cb() */
/*
** provider_setup() -- Set connection properties based on the
** directory provider.
*/
CS_RETCODE
provider_setup(conn)
CS_CONNECTION *conn;
{
CS_RETCODE ret;
CS_CHAR scratch_str[512];
/*
** We just print out the default directory provider name. If we
** were tailoring this example for a specific provider name, we
** could set properties here such as CS_DS_DITBASE.
**
** Instead, we depend on the default DIT-base being set in the driver
** configuration file (libtcl.cfg on most platforms).
*/
ret = ct_con_props(conn, CS_GET, CS_DS_PROVIDER, scratch_str,
512, NULL);
if (ret != CS_SUCCEED)
{
ex_error(
"provider_setup: Could not get directory provider name.");
return CS_FAIL;
}
fprintf(stdout, "\nProvider is %s\n\n", scratch_str);
return CS_SUCCEED;
} /* provider_setup() */
/*
** choose_server() -- Show the contents of the server list to
** the user. Let the user choose a server to connect to.
**
** Parameters
** conn -- Connection that the server objects were obtained
** with (the CS_CONNECTION pointer that was passed to
** ct_ds_objinfo)
** server_list -- Pointer to the server list.
** namebuf -- Buffer to receive the distinguished name of the
** server that the user picks.
** buflen -- Length of namebuf, in bytes.
** outlen -- If supplied, will be set to number of bytes written
** to namebuf.
**
** Returns
** 0 -- namebuf contains the name of the server to connect to.
** 1 -- user elected to quit the program.
** < 0 -- error occurred.
*/
CS_RETCODE
choose_server(conn, server_list, namebuf, buflen, outlen)
CS_CONNECTION *conn;
SERVER_INFO_LIST *server_list;
CS_CHAR namebuf[];
CS_INT buflen;
CS_INT *outlen;
{
CS_RETCODE ret;
CS_INT pos;
CS_CHAR in_buf[CHOOSE_SERVER_MAX_INPUT];
CS_DS_OBJECT *ds_object;
CS_INT return_cond = -1;
CS_INT intval;
/*
** Check for input errors.
*/
if (namebuf == NULL || buflen < 1)
{
ex_error("choose_server: buffer must be supplied.");
return -1;
}
/*
** Make the output fail safe.
*/
namebuf[0] = '\0';
if (outlen != NULL)
{
*outlen = 0;
}
/*
** Display the attributes for each server in the list. After each,
** pause and ask the user if it's the one to connect to.
*/
pos = 1;
while (pos <= sil_list_len(server_list) && return_cond == -1)
{
ret = sil_extract_object(server_list, pos, &ds_object);
if (ret != CS_SUCCEED)
{
ex_error(
"choose_server: sil_extract_object() failed.");
return -1;
}
if (ds_object != NULL)
{
/*
** Show the server's attributes that were
** retrieved from the directory.
*/
ret = show_server_info(ds_object, stdout);
if (ret != CS_SUCCEED)
{
ex_error(
"choose_server: show_server_info() failed.");
return -1;
}
/*
** Ask the user what to do next.
*/
fprintf(stdout, "\n[%ld of %ld] ",
(long)pos, (long)sil_list_len(server_list));
fprintf(stdout,
"Connect (c), see next (n), skip to (#), or quit (q): ");
(CS_VOID)fgets(in_buf, CHOOSE_SERVER_MAX_INPUT, stdin);
switch ((int)in_buf[0])
{
case 'c':
case 'C':
/*
** User chose this server to connect to.
** Copy the object's distinguished name
** into the caller's buffer.
*/
ret = ct_ds_objinfo(ds_object, CS_GET,
CS_DS_DIST_NAME, CS_UNUSED,
(CS_VOID *)namebuf, buflen, &intval);
if (ret != CS_SUCCEED)
{
ex_error(
"choose_server: ct_ds_objinfo(NAME) failed.");
return -1;
}
/*
** Set the caller's outlen variable if it
** was supplied.
*/
if (outlen != NULL)
{
*outlen = intval;
}
return_cond = 0;
break;
case 'q':
case 'Q':
/*
** User is tired and wants to quit.
*/
return_cond = 1;
break;
case 'n':
case 'N':
default:
/*
** Try to convert the input to an integer
** -- if successful, then skip to that
** number. Otherwise, default action shows
** the next server in the list.
*/
intval = atoi(in_buf);
if (intval != 0)
{
/*
** Skip to a different server
** number.
*/
if (intval > 0
&& intval <= sil_list_len(server_list))
{
pos = intval;
}
else
{
ex_error("Not that many servers.");
}
}
else
{
/*
** Show next.
*/
++pos;
}
fprintf(stdout, "\n");
break;
} /* switch */
} /* if */
} /* while */
return return_cond;
} /* choose_server() */
/*
** show_server_info()
** Selectively display the attributes of a server directory
** object.
**
** Parameters
** ds_object -- Pointer to the CS_DS_OBJECT that describes the
** server's directory entry.
** outfile -- Open FILE handle to write the output to.
**
** Dependencies
** Reads the contents of the AttributesToDisplay global array.
**
** Returns
** CS_SUCCEED or CS_FAIL.
*/
CS_RETCODE
show_server_info(ds_object, outfile)
CS_DS_OBJECT *ds_object;
FILE *outfile;
{
CS_RETCODE ret;
CS_CHAR scratch_str[512];
CS_INT outlen;
CS_INT cur_attr;
CS_ATTRIBUTE attr_metadata;
CS_ATTRVALUE *p_attrvals;
/*
** Distinguished name of the object.
*/
ret = ct_ds_objinfo(ds_object, CS_GET, CS_DS_DIST_NAME, CS_UNUSED,
(CS_VOID *)scratch_str, CS_SIZEOF(scratch_str),
&outlen);
if (ret != CS_SUCCEED)
{
ex_error("show_server_info: get distinguished name failed.");
return CS_FAIL;
}
fprintf(outfile, "Name in directory: %s\n", scratch_str);
for (cur_attr = 0; cur_attr < N_ATTRIBUTES; cur_attr++)
{
/*
** Look for the attribute. attr_get_by_type() fails if the
** object instance does not contain a value for the
** attribute. If this happens, we just go on to the next
** attribute.
*/
ret = attr_get_by_type(ds_object,
AttributesToDisplay[cur_attr].type_string,
&attr_metadata, &p_attrvals);
if (ret == CS_SUCCEED)
{
fprintf(outfile,
"%s:\n", AttributesToDisplay[cur_attr].english_name);
/*
** Display the attribute values.
*/
ret = attr_display_values(&attr_metadata,
p_attrvals, outfile);
if (ret != CS_SUCCEED)
{
ex_error(
"show_server_info: display attribute values failed.");
free(p_attrvals);
return CS_FAIL;
}
free(p_attrvals);
}
} /* for */
return CS_SUCCEED;
} /* show_server_info() */
/*
** get_attr_by_type()
** Get metadata and attribute values for a given attribute type.
**
** Parameters
** ds_object -- Pointer to a valid CS_DS_OBJECT hidden structure.
** attr_type_str -- Null-terminated string containing the OID for the
** desired attribute type.
** attr_metadata -- Pointer to a CS_ATTRIBUTE structure to
** fill in.
** p_attrvals -- Address of a CS_ATTRVALUE union pointer.
** If successful, this routine allocates an array
** of size attr_metadata->numvalues, retrieves values into
** it, and returns the array address in *p_attr_values.
** NOTE: The caller must free this array when it is no longer
** needed.
**
** Returns
** CS_FAIL if no attribute of the specified type was found.
** CS_SUCCEED for success.
*/
CS_RETCODE
attr_get_by_type(ds_object, attr_type_str, attr_metadata, p_attrvals)
CS_DS_OBJECT *ds_object;
CS_CHAR *attr_type_str;
CS_ATTRIBUTE *attr_metadata;
CS_ATTRVALUE **p_attrvals;
{
CS_RETCODE ret;
CS_INT num_attrs;
CS_INT cur_attr;
CS_INT outlen;
CS_INT buflen;
CS_BOOL found = CS_FALSE;
/*
** Check input pointers. If not NULL, make them fail safe.
*/
if (attr_metadata == NULL || p_attrvals == NULL)
{
return CS_FAIL;
}
attr_metadata->attr_numvals = 0;
*p_attrvals = NULL;
/*
** Get number of attributes.
*/
ret = ct_ds_objinfo(ds_object, CS_GET, CS_DS_NUMATTR, CS_UNUSED,
(CS_VOID *)&num_attrs, CS_SIZEOF(num_attrs),
NULL);
if (ret != CS_SUCCEED)
{
ex_error(
"attr_get_by_type: get number of attributes failed.");
return CS_FAIL;
}
/*
** Look for the matching attribute, get the values if found.
*/
for (cur_attr = 1;
(cur_attr <= num_attrs) && (found != CS_TRUE);
cur_attr++)
{
/*
** Get the attribute's metadata.
*/
ret = ct_ds_objinfo(ds_object, CS_GET, CS_DS_ATTRIBUTE,
cur_attr, (CS_VOID *)attr_metadata,
CS_SIZEOF(CS_ATTRIBUTE), NULL);
if (ret != CS_SUCCEED)
{
ex_error("attr_get_by_type: get attribute failed.");
return CS_FAIL;
}
/*
** Check for a match.
*/
if (match_OID(&(attr_metadata->attr_type), attr_type_str))
{
found = CS_TRUE;
/*
** Get the values -- we first allocate an array of
** CS_ATTRVALUE unions.
*/
if (attr_metadata->attr_numvals <= 0)
{
ex_error(
"attr_get_by_type: bad numvals field!");
return CS_FAIL;
}
*p_attrvals = (CS_ATTRVALUE *)
malloc(sizeof(CS_ATTRVALUE)
* (attr_metadata->attr_numvals));
if (p_attrvals == NULL)
{
ex_error("attr_get_by_type: out of memory!");
return CS_FAIL;
}
buflen = CS_SIZEOF(CS_ATTRVALUE)
* (attr_metadata->attr_numvals);
ret = ct_ds_objinfo(ds_object, CS_GET,
CS_DS_ATTRVALS, cur_attr,
(CS_VOID *)(*p_attrvals),
buflen, &outlen);
if (ret != CS_SUCCEED)
{
ex_error(
"attr_get_by_type: get attribute values failed.");
free(*p_attrvals);
*p_attrvals = NULL;
attr_metadata->attr_numvals = 0;
return CS_FAIL;
}
}
}
/*
** Got the attribute.
*/
if (found == CS_TRUE)
{
return CS_SUCCEED;
}
/*
** Not found.
*/
attr_metadata->attr_numvals = 0;
return CS_FAIL;
} /* attr_get_by_type() */
/*
** attr_display_values()
** Writes an attribute's values to the specified text
** file.
**
** Parameters
** attr_metadata -- address of the CS_ATTRIBUTE structure that
** contains metadata for the attribute.
** attr_vals -- address of an array of CS_ATTRVALUE structures.
** This function assumes length is attr_metadata->attr_numvals
** and value syntax is attr_metadata->attr_syntax.
** outfile -- Open FILE handle to write to.
**
** Returns
** CS_SUCCEED or CS_FAIL.
*/
CS_RETCODE
attr_display_values(attr_metadata, attr_vals, outfile)
CS_ATTRIBUTE *attr_metadata;
CS_ATTRVALUE *attr_vals;
FILE *outfile;
{
CS_INT i;
CS_CHAR outbuf[CS_MAX_DS_STRING * 3];
CS_RETCODE ret;
/*
** Print each value.
*/
for (i = 0; i < attr_metadata->attr_numvals; i++)
{
ret = attr_val_as_string(attr_metadata, attr_vals + i,
outbuf, CS_MAX_DS_STRING * 3, NULL);
if (ret != CS_SUCCEED)
{
ex_error(
"attr_display_values: attr_val_as_string() failed.");
return CS_FAIL;
}
fprintf(outfile, "\t%s\n", outbuf);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -