Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
GetSetOptions.c
/* |
File: GetSetOptions.c |
Contains: Sample for getting and setting options using the various |
option management routines. |
Written by: Quinn "The Eskimo!" |
Copyright: Copyright © 1997-2001 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
2/18/2001 Chad Jones Updated for Codewarrior IDE 4.1 and Carbonized for OSX |
7/22/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
///////////////////////////////////////////////////////////////////// |
// Need to include to be carbonized |
#if defined(__MWERKS__) |
# include <carbon.h> |
# include <OpenTransport.h> |
# include <OpenTptInternet.h> |
# include <OpenTptSerial.h> |
# include <SIOUX.h> |
#else |
# include <CoreServices/CoreServices.h> |
#endif |
# include <stdio.h> |
///////////////////////////////////////////////////////////////////// |
// This MoreAssertQ is used in replacement for OTAssert under carbon because |
// OTAssert is not in carbon. |
static void MoreAssertQ(Boolean mustBeTrue) |
{ |
if ( ! mustBeTrue ) { |
DebugStr("\pGetSetOptions: Assertion failure."); |
} |
} |
///////////////////////////////////////////////////////////////////// |
static OTResult SetFourByteOption(EndpointRef ep, |
OTXTILevel level, |
OTXTIName name, |
UInt32 value) |
// level and name must denote a four byte option that is |
// appropriate for the endpoint ep. This routine sets the |
// option to value. ep is assumed to be in synchronous |
// mode. |
// |
// If all goes well, the result is noErr. If an error |
// occurs, the result is negative. If the option could not |
// be negotiated, a positive result being one of (T_FAILURE, |
// T_PARTSUCCESS, T_READONLY, T_NOTSUPPORT) is returned |
{ |
OTResult err; |
TOption option; |
TOptMgmt request; |
TOptMgmt result; |
// Set up the option buffer to reflect the specific option |
// and value we want to set. We use a TOption structure |
// to represent the option buffer. TOption is specifically |
// defined to allow easy construction of 4 byte options. |
// If you want to negotiate different size options, or |
// multiple options in a single call, then constructing |
// the option buffer is a little trickier |
option.len = kOTFourByteOptionSize; |
option.level = level; |
option.name = name; |
option.status = 0; |
option.value[0] = value; |
// Set up the request for OTOptionManagement to point |
// to the option buffer we just filled out, and tell |
// it that we want to negotiate (ie set) the option. |
request.opt.buf = (UInt8 *) &option; |
request.opt.len = sizeof(option); |
request.flags = T_NEGOTIATE; |
// Set up the reply for OTOptionManagement. This is where |
// OTOptionManagement puts the result of the negotiation. |
result.opt.buf = (UInt8 *) &option; |
result.opt.maxlen = sizeof(option); |
// Call OTOptionManagement and then check that the value |
// was negotiated successfully. Any value other than |
// T_SUCCESS is reported via the error result. |
err = OTOptionManagement(ep, &request, &result); |
if (err == noErr) { |
if (option.status != T_SUCCESS) { |
err = option.status; |
} |
} |
return (err); |
} |
///////////////////////////////////////////////////////////////////// |
static OTResult GetFourByteOption(EndpointRef ep, |
OTXTILevel level, |
OTXTIName name, |
UInt32 *value) |
// level and name must denote a four byte option that is |
// appropriate for the endpoint ep. This routine gets the |
// current option setting and puts it in the the variable |
// pointed to by value. ep is assumed to be in synchronous |
// mode. |
// |
// If all goes well, the result is noErr. If an error |
// occurs, the result is negative. If the option could not |
// be read, a positive result being one of (T_FAILURE, |
// T_PARTSUCCESS, T_NOTSUPPORT) is returned |
{ |
OTResult err; |
TOption option; |
TOptMgmt request; |
TOptMgmt result; |
// Set up the option buffer to reflect the specific option |
// and value we want to set. We use a TOption structure |
// to represent the option buffer. TOption is specifically |
// defined to allow easy construction of 4 byte options. |
// If you want to negotiate different size options, or |
// multiple options in a single call, then constructing |
// the option buffer is a little trickier |
option.len = kOTFourByteOptionSize; |
option.level = level; |
option.name = name; |
option.status = 0; |
option.value[0] = 0; // Ignored because we're getting the value. |
// Set up the request for OTOptionManagement to point |
// to the option buffer we just filled out, and tell |
// it that we want to get the current value of the option. |
request.opt.buf = (UInt8 *) &option; |
request.opt.len = sizeof(option); |
request.flags = T_CURRENT; |
// Set up the reply for OTOptionManagement. This is where |
// OTOptionManagement puts the result of the negotiation. |
result.opt.buf = (UInt8 *) &option; |
result.opt.maxlen = sizeof(option); |
// Call OTOptionManagement and then check that the value |
// was read successfully. Any status other than |
// T_SUCCESS or T_READONLY is reported via the error |
// result. |
err = OTOptionManagement(ep, &request, &result); |
if (err == noErr) { |
switch (option.status) { |
case T_SUCCESS: |
case T_READONLY: |
*value = option.value[0]; |
break; |
default: |
err = option.status; |
break; |
} |
} |
return (err); |
} |
///////////////////////////////////////////////////////////////////// |
static OSStatus PrintOptionBuffer(const TNetbuf *optionBuffer) |
// Print a summary of the optionBuffer to stdout. |
// Basically the call enumerates the option buffer using |
// OTNextOption, and prints the level, name, size and status |
// of each of the options in the buffer. |
{ |
OSStatus err; |
TOption *currentOption; |
currentOption = nil; |
do { |
err = OTNextOption(optionBuffer->buf, optionBuffer->len, ¤tOption); |
if (err == noErr && currentOption != nil) { |
printf("Level = $%08lx, Name = $%08lx, Data Length = %ld, Status = $%08lx\n", |
currentOption->level, |
currentOption->name, |
currentOption->len - kOTOptionHeaderSize, |
currentOption->status); |
fflush(stdout); |
} |
} while (err == noErr && currentOption != nil); |
return (err); |
} |
///////////////////////////////////////////////////////////////////// |
static OSStatus PrintAllOptionsAtLevel(EndpointRef ep, OTXTILevel level) |
// Gets all of the options for the endpoint ep at the specified |
// level and prints a summary of them to stdout. |
{ |
OSStatus err; |
TEndpointInfo epInfo; |
TOptionHeader requestOption; |
void *resultOptionBuffer; |
TOptMgmt request; |
TOptMgmt result; |
resultOptionBuffer = nil; |
// First call OTGetEndpointInfo to find out the maximum |
// size of the options for this type of endpoint and then |
// allocate that size buffer to hold the resulting options. |
err = OTGetEndpointInfo(ep, &epInfo); |
if (err == noErr) { |
resultOptionBuffer = OTAllocMemInContext(epInfo.options,nil); |
if (resultOptionBuffer == nil) { |
err = kENOMEMErr; |
} |
} |
// Call OTOptionManagement to get the current value (T_CURRENT) |
// of all of the options (ie T_ALLOPT) of the specified level. |
// The resulting options go into resultOptionBuffer, which we |
// have just allocated. |
if (err == noErr) { |
requestOption.len = kOTOptionHeaderSize; |
requestOption.level = level; |
requestOption.name = T_ALLOPT; |
requestOption.status = 0; |
request.opt.buf = (UInt8 *) &requestOption; |
request.opt.len = sizeof(requestOption); |
request.flags = T_CURRENT; |
result.opt.buf = resultOptionBuffer; |
result.opt.maxlen = epInfo.options; |
err = OTOptionManagement(ep, &request, &result); |
} |
// Now that we have the options, print them to stdout. |
if (err == noErr) { |
err = PrintOptionBuffer(&result.opt); |
printf("\n"); |
fflush(stdout); |
} |
// Clean up. |
if (resultOptionBuffer != nil) { |
OTFreeMem(resultOptionBuffer); |
} |
return (err); |
} |
///////////////////////////////////////////////////////////////////// |
int main(void) |
// A simple main line that demonstrates the use of the various |
// functions defined above. The basic idea is to create |
// an endpoint, get the value of the kIP_REUSEADDR option, then |
// change it to true, and read it back to verify that the change |
// worked. We then do a few other interesting things with |
// various miscellaneous options API routines. |
{ |
OSStatus err; |
OSStatus junk; |
EndpointRef ep; |
UInt32 value; |
#if defined(__MWERKS__) |
SIOUXSettings.autocloseonquit = FALSE; // don't close the SIOUX window on program termination |
SIOUXSettings.asktosaveonclose = FALSE; // don't offer to save on a close |
#endif |
err = InitOpenTransportInContext(kInitOTForApplicationMask, nil); |
if (err == noErr) { |
ep = OTOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0, nil, &err,nil); |
if (err == noErr) { |
printf("\nGetting and Setting IP_REUSEADDR.\n"); |
fflush(stdout); |
err = GetFourByteOption(ep, INET_IP, kIP_REUSEADDR, &value); |
if (err == noErr) { |
printf("Default value = %ld\n", value); |
fflush(stdout); |
} |
if (err == noErr) { |
err = SetFourByteOption(ep, INET_IP, kIP_REUSEADDR, true); |
} |
if (err == noErr) { |
err = GetFourByteOption(ep, INET_IP, kIP_REUSEADDR, &value); |
if (err == noErr) { |
printf("New value = %ld\n", value); |
fflush(stdout); |
} |
} |
if (err == noErr) { |
printf("\nPrinting Options Piecemeal at Level INET_IP.\n"); |
err = PrintAllOptionsAtLevel(ep, INET_IP); |
fflush(stdout); |
} |
//If you used the pre-carbon sampes of this sample code you may be wondering where calls to |
//PrintOptionsForConfiguration and BuildAndPrintOptions are. |
//In carbon and OSX these calls have no meaning because there is no concept of options as |
//strings in OSX or carbon. Thus they have been removed completely from this sample code. |
junk = OTCloseProvider(ep); |
MoreAssertQ(junk == noErr); //False if: Closing the endpoint failed. |
} |
CloseOpenTransportInContext(nil); |
} |
if (err == noErr) { |
printf("Success.\n"); |
} else { |
printf("Failed with error %ld.\n", err); |
} |
fflush(stdout); |
return(0); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14