/** Unpack an entire setting description from the buffer * * @param pBuffer the buffer to unpack from * @param index the index in the buffer to start at * @param size the size of the buffer in bytes * @param setting the structure to hold the setting value * * @return the new index for the next piece of data or 0 if an error occurs. */ static int unpackSetting(unsigned char *pBuffer, int index, int size, SettingDescription &setting) { if ((index + 1)>=size) // Make sure we have the type modifier at least return 0; // 1 byte for type setting.typeAndModifier = pBuffer[index++]; // The name if ((index=unpackString(pBuffer, index, size, &setting.name))<=0) return index; // And the value itself switch(setting.typeAndModifier & SETTING_TYPE_MASK) { case StringSetting: index = unpackString(pBuffer, index, size, &setting.value.string); break; case IntegerSetting: index = unpackInteger(pBuffer, index, size, setting.value.integer); break; case BooleanSetting: index = unpackBoolean(pBuffer, index, size, setting.value.boolean); break; case NumberSetting: index = unpackDouble(pBuffer, index, size, setting.value.number); break; default: index = 0; } return index; }
int EEmcDbCCIO<eemcDbPIXname>::print(char *line, char *name, int i) { char txt [EEMCDbMaxName]; unpackString(data()->tubeName ,i,EEMCDbMaxName ,txt); return (sprintf(line,"%s %s\n",name,txt)>=2); }
int EEmcDbCCIO<T>::write(FILE *f) { char line[MaxLine]; T *s = data(); for(int i=0;i<getSize();i++) { char tn[EEMCDbMaxName]; unpackString(s->name ,i,EEMCDbMaxName ,tn); if(*tn==0x00) break; print(line,tn,i); fputs(line,f); } setComment(s->comment); return 1; }
const uint8_t *unpackFilesIncoming( std::unordered_multimap<std::string, Transfer::FileIncoming> &map, const uint8_t *src ) { size_t count; src = unpackNumber(&count, src); for (size_t i = 0; i < count; ++i) { std::string key; src = unpackString(key, src); std::string file_tmp_name; src = unpackString(file_tmp_name, src); std::string file_name; src = unpackString(file_name, src); std::string file_type; src = unpackString(file_type, src); size_t file_size; src = unpackNumber(&file_size, src); map.emplace( std::move(key), Transfer::FileIncoming( std::move(file_tmp_name), std::move(file_name), std::move(file_type), file_size ) ); } return src; }
void CIcqProto::handleAuthKeyResponse(BYTE *buf, size_t wPacketLen, serverthread_info *info) { char szKey[64] = {0}; mir_md5_state_t state; BYTE digest[16]; debugLogA("Received %s", "ICQ_SIGNON_AUTH_KEY"); if (wPacketLen < 2) { debugLogA("Malformed %s", "ICQ_SIGNON_AUTH_KEY"); icq_LogMessage(LOG_FATAL, LPGEN("Secure login failed.\nInvalid server response.")); SetCurrentStatus(ID_STATUS_OFFLINE); return; } size_t wKeyLen; unpackWord(&buf, &wKeyLen); wPacketLen -= 2; if (!wKeyLen || wKeyLen > wPacketLen || wKeyLen > sizeof(szKey)) { debugLogA("Invalid length in %s: %u", "ICQ_SIGNON_AUTH_KEY", wKeyLen); icq_LogMessage(LOG_FATAL, LPGEN("Secure login failed.\nInvalid key length.")); SetCurrentStatus(ID_STATUS_OFFLINE); return; } unpackString(&buf, szKey, wKeyLen); mir_md5_init(&state); mir_md5_append(&state, info->szAuthKey, (int)info->wAuthKeyLen); mir_md5_finish(&state, digest); mir_md5_init(&state); mir_md5_append(&state, (LPBYTE)szKey, (int)wKeyLen); mir_md5_append(&state, digest, 16); mir_md5_append(&state, (LPBYTE)CLIENT_MD5_STRING, sizeof(CLIENT_MD5_STRING)-1); mir_md5_finish(&state, digest); debugLogA("Sending ICQ_SIGNON_LOGIN_REQUEST to login server"); sendClientAuth((char*)digest, 0x10, TRUE); }
void CIcqProto::handleDirectMessage(directconnect* dc, PBYTE buf, WORD wLen) { WORD wCommand; WORD wCookie; BYTE bMsgType,bMsgFlags; WORD wStatus; WORD wFlags; WORD wTextLen; char* pszText = NULL; // The first part of the packet should always be at least 31 bytes if (wLen < 31) { NetLog_Direct("Error during parsing of DC packet 2 PEER_MSG (too short)"); return; } // Skip packet checksum buf += 4; wLen -= 4; // Command: // 0x07d0 = 2000 - cancel given message. // 0x07da = 2010 - acknowledge message. // 0x07ee = 2030 - normal message/request. unpackLEWord(&buf, &wCommand); wLen -= 2; // Unknown, always 0xe (14) buf += 2; wLen -= 2; // Sequence number unpackLEWord(&buf, &wCookie); wLen -=2; // Unknown, always zeroes buf += 12; wLen -= 12; // Peer message type unpackByte(&buf, &bMsgType); // Peer message flags unpackByte(&buf, &bMsgFlags); wLen -= 2; // The current status of the user, or whether the message was accepted or not. // 0x00 - user is online, or message was receipt, or file transfer accepted // 0x01 - refused // 0x04 - auto-refused, because of away // 0x09 - auto-refused, because of occupied // 0x0a - auto-refused, because of dnd // 0x0e - auto-refused, because of na unpackLEWord(&buf, &wStatus); wLen -= 2; // Flags, or priority // Seen: 1 - Chat request // 0 - File auto accept (type 3) // 33 - priority ? unpackLEWord(&buf, &wFlags); wLen -= 2; // Messagetext. This is either the status message or the actual message // when this is a PEER_MSG_MSG packet unpackLEWord(&buf, &wTextLen); if (wTextLen > 0) { pszText = (char*)_alloca(wTextLen+1); unpackString(&buf, pszText, wTextLen); pszText[wTextLen] = '\0'; } wLen = (wLen - 2) - wTextLen; #ifdef _DEBUG NetLog_Direct("Handling PEER_MSG '%s', command %u, cookie %u, messagetype %u, messageflags %u, status %u, flags %u", pszText, wCommand, wCookie, bMsgType, bMsgFlags, wStatus, wFlags); #else NetLog_Direct("Message through direct - UID: %u", dc->dwRemoteUin); #endif // The remaining actual message is handled either as a status message request, // a greeting message, a acknowledge or a normal (text, url, file) message if (wCommand == DIRECT_MESSAGE) switch (bMsgType) { case MTYPE_FILEREQ: // File inits handleFileRequest(buf, wLen, dc->dwRemoteUin, wCookie, 0, 0, pszText, 7, TRUE); break; case MTYPE_AUTOAWAY: case MTYPE_AUTOBUSY: case MTYPE_AUTONA: case MTYPE_AUTODND: case MTYPE_AUTOFFC: { char **szMsg = MirandaStatusToAwayMsg(AwayMsgTypeToStatus(bMsgType)); if (szMsg) icq_sendAwayMsgReplyDirect(dc, wCookie, bMsgType, ( const char** )szMsg); } break; case MTYPE_PLUGIN: // Greeting handleDirectGreetingMessage(dc, buf, wLen, wCommand, wCookie, bMsgType, bMsgFlags, wStatus, wFlags, pszText); break; default: { message_ack_params pMsgAck = {0}; uid_str szUID; buf -= wTextLen; wLen += wTextLen; pMsgAck.bType = MAT_DIRECT; pMsgAck.pDC = dc; pMsgAck.wCookie = wCookie; pMsgAck.msgType = bMsgType; pMsgAck.bFlags = bMsgFlags; handleMessageTypes(dc->dwRemoteUin, szUID, time(NULL), 0, 0, wCookie, dc->wVersion, (int)bMsgType, (int)bMsgFlags, 0, (DWORD)wLen, wTextLen, (char*)buf, MTF_DIRECT, &pMsgAck); break; } } else if (wCommand == DIRECT_ACK) { if (bMsgFlags == 3) { // this is status reply uid_str szUID; buf -= wTextLen; wLen += wTextLen; handleMessageTypes(dc->dwRemoteUin, szUID, time(NULL), 0, 0, wCookie, dc->wVersion, (int)bMsgType, (int)bMsgFlags, 2, (DWORD)wLen, wTextLen, (char*)buf, MTF_DIRECT, NULL); } else { MCONTACT hCookieContact; cookie_message_data *pCookieData = NULL; if (!FindCookie(wCookie, &hCookieContact, (void**)&pCookieData)) { NetLog_Direct("Received an unexpected direct ack"); } else if (hCookieContact != dc->hContact) { NetLog_Direct("Direct Contact does not match Cookie Contact(0x%x != 0x%x)", dc->hContact, hCookieContact); ReleaseCookie(wCookie); // This could be a bad idea, but I think it is safe } else { // the ack is correct int ackType = -1; switch (bMsgType) { case MTYPE_PLAIN: ackType = ACKTYPE_MESSAGE; break; case MTYPE_URL: ackType = ACKTYPE_URL; break; case MTYPE_CONTACTS: ackType = ACKTYPE_CONTACTS; break; case MTYPE_FILEREQ: // File acks handleFileAck(buf, wLen, dc->dwRemoteUin, wCookie, wStatus, pszText); break; case MTYPE_PLUGIN: // Greeting handleDirectGreetingMessage(dc, buf, wLen, wCommand, wCookie, bMsgType, bMsgFlags, wStatus, wFlags, pszText); break; default: NetLog_Direct("Skipped packet from direct connection"); break; } if (ackType != -1) { // was a good ack to broadcast ? ProtoBroadcastAck(dc->hContact, ackType, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); ReleaseCookie(wCookie); } } } } else if (wCommand == DIRECT_CANCEL) { NetLog_Direct("Cannot handle abort messages yet... :("); } else NetLog_Direct("Unknown wCommand, packet skipped"); }
void CIcqProto::handleDirectGreetingMessage(directconnect* dc, PBYTE buf, WORD wLen, WORD wCommand, WORD wCookie, BYTE bMsgType, BYTE bMsgFlags, WORD wStatus, WORD wFlags, char* pszText) { DWORD dwLengthToEnd; DWORD dwDataLength; char* pszFileName = NULL; int typeId; WORD qt; #ifdef _DEBUG NetLog_Direct("Handling PEER_MSG_GREETING, command %u, cookie %u, messagetype %u, messageflags %u, status %u, flags %u", wCommand, wCookie, bMsgType, bMsgFlags, wStatus, wFlags); #endif NetLog_Direct("Parsing Greeting message through direct"); if (!unpackPluginTypeId(&buf, &wLen, &typeId, &qt, TRUE)) return; // Length of remaining data unpackLEDWord(&buf, &dwLengthToEnd); if (dwLengthToEnd < 4 || dwLengthToEnd > wLen) { NetLog_Direct("Error: Sanity checking failed (%d) in handleDirectGreetingMessage, datalen %u wLen %u", 2, dwLengthToEnd, wLen); return; } // Length of message/reason unpackLEDWord(&buf, &dwDataLength); wLen -= 4; if (dwDataLength > wLen) { NetLog_Direct("Error: Sanity checking failed (%d) in handleDirectGreetingMessage, datalen %u wLen %u", 3, dwDataLength, wLen); return; } if (typeId == MTYPE_FILEREQ && wCommand == DIRECT_MESSAGE) { char* szMsg; NetLog_Direct("This is file request"); szMsg = (char*)_alloca(dwDataLength+1); unpackString(&buf, szMsg, (WORD)dwDataLength); szMsg[dwDataLength] = '\0'; wLen = wLen - (WORD)dwDataLength; handleFileRequest(buf, wLen, dc->dwRemoteUin, wCookie, 0, 0, szMsg, 8, TRUE); } else if (typeId == MTYPE_FILEREQ && wCommand == DIRECT_ACK) { char* szMsg; NetLog_Direct("This is file ack"); szMsg = (char*)_alloca(dwDataLength+1); unpackString(&buf, szMsg, (WORD)dwDataLength); szMsg[dwDataLength] = '\0'; wLen = wLen - (WORD)dwDataLength; // 50 - file request granted/refused handleFileAck(buf, wLen, dc->dwRemoteUin, wCookie, wStatus, szMsg); } else if (typeId && wCommand == DIRECT_MESSAGE) { uid_str szUID; message_ack_params pMsgAck = {0}; pMsgAck.bType = MAT_DIRECT; pMsgAck.pDC = dc; pMsgAck.wCookie = wCookie; pMsgAck.msgType = typeId; handleMessageTypes(dc->dwRemoteUin, szUID, time(NULL), 0, 0, wCookie, dc->wVersion, typeId, 0, 0, dwLengthToEnd, (WORD)dwDataLength, (char*)buf, MTF_PLUGIN | MTF_DIRECT, &pMsgAck); } else if (typeId == MTYPE_STATUSMSGEXT && wCommand == DIRECT_ACK) { // especially for icq2003b NetLog_Direct("This is extended status reply"); char *szMsg = (char*)_alloca(dwDataLength+1); uid_str szUID; unpackString(&buf, szMsg, (WORD)dwDataLength); szMsg[dwDataLength] = '\0'; handleMessageTypes(dc->dwRemoteUin, szUID, time(NULL), 0, 0, wCookie, dc->wVersion, (int)(qt + 0xE7), 3, 2, (DWORD)wLen, (WORD)dwDataLength, szMsg, MTF_PLUGIN | MTF_DIRECT, NULL); } else if (typeId && wCommand == DIRECT_ACK) { MCONTACT hCookieContact; cookie_message_data *pCookieData = NULL; if (!FindCookie(wCookie, &hCookieContact, (void**)&pCookieData)) { NetLog_Direct("Received an unexpected direct ack"); } else if (hCookieContact != dc->hContact) { NetLog_Direct("Direct Contact does not match Cookie Contact(0x%x != 0x%x)", dc->hContact, hCookieContact); ReleaseCookie(wCookie); // This could be a bad idea, but I think it is safe } else { int ackType = -1; switch (typeId) { case MTYPE_MESSAGE: ackType = ACKTYPE_MESSAGE; break; case MTYPE_URL: ackType = ACKTYPE_URL; break; case MTYPE_CONTACTS: ackType = ACKTYPE_CONTACTS; break; case MTYPE_SCRIPT_NOTIFY: { char *szMsg; szMsg = (char*)_alloca(dwDataLength + 1); if (dwDataLength > 0) memcpy(szMsg, buf, dwDataLength); szMsg[dwDataLength] = '\0'; handleXtrazNotifyResponse(dc->dwRemoteUin, dc->hContact, wCookie, szMsg, dwDataLength); } break; default: NetLog_Direct("Skipped packet from direct connection"); break; } if (ackType != -1) { // was a good ack to broadcast ? ProtoBroadcastAck(dc->hContact, ackType, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); } // Release cookie ReleaseCookie(wCookie); } } else NetLog_Direct("Unsupported plugin message type %s", typeId); }
void CIcqProto::handleFileAck(PBYTE buf, WORD wLen, DWORD dwUin, DWORD dwCookie, WORD wStatus, char* pszText) { char* pszFileName = NULL; DWORD dwFileSize; HANDLE hCookieContact; WORD wPort; WORD wFilenameLength; filetransfer* ft; // Find the filetransfer that belongs to this response if (!FindCookie(dwCookie, &hCookieContact, (void**)&ft)) { NetLog_Direct("Error: Received unexpected file transfer request response"); return; } FreeCookie(dwCookie); if (hCookieContact != HContactFromUIN(dwUin, NULL)) { NetLog_Direct("Error: UINs do not match in file transfer request response"); return; } // If status != 0, a request has been denied if (wStatus != 0) { NetLog_Direct("File transfer denied by %u.", dwUin); ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)ft, 0); FreeCookie(dwCookie); return; } if (wLen < 6) { // sanity check NetLog_Direct("Ignoring malformed file transfer request response"); return; } // Port to connect to unpackWord(&buf, &wPort); ft->dwRemotePort = wPort; wLen -= 2; // Unknown buf += 2; wLen -= 2; // Filename unpackLEWord(&buf, &wFilenameLength); if (wFilenameLength > 0) { if (wFilenameLength > wLen - 2) wFilenameLength = wLen - 2; pszFileName = (char*)_alloca(wFilenameLength+1); unpackString(&buf, pszFileName, wFilenameLength); pszFileName[wFilenameLength] = '\0'; } wLen = wLen - 2 - wFilenameLength; if (wLen >= 4) { // Total filesize unpackLEDWord(&buf, &dwFileSize); wLen -= 4; } else dwFileSize = 0; NetLog_Direct("File transfer ack from %u, port %u, name %s, size %u", dwUin, ft->dwRemotePort, pszFileName, dwFileSize); ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)ft, 0); OpenDirectConnection(ft->hContact, DIRECTCONN_FILE, ft); }
// pszDescription points to a string with the reason // buf points to the first data after the string void CIcqProto::handleFileRequest(PBYTE buf, WORD wLen, DWORD dwUin, DWORD dwCookie, DWORD dwID1, DWORD dwID2, char* pszDescription, int nVersion, BOOL bDC) { BOOL bEmptyDesc = FALSE; if (strlennull(pszDescription) == 0) { pszDescription = Translate("No description given"); bEmptyDesc = TRUE; } // Empty port+pad buf += 4; wLen -= 4; // Filename WORD wFilenameLength; unpackLEWord(&buf, &wFilenameLength); if (!wFilenameLength) { NetLog_Direct("Ignoring malformed file send request"); return; } char *pszFileName = (char*)_alloca(wFilenameLength + 1); unpackString(&buf, pszFileName, wFilenameLength); pszFileName[wFilenameLength] = '\0'; wLen = wLen - 2 - wFilenameLength; // Total filesize DWORD dwFileSize; unpackLEDWord(&buf, &dwFileSize); wLen -= 4; int bAdded; HANDLE hContact = HContactFromUIN(dwUin, &bAdded); // Initialize a filetransfer struct filetransfer *ft = CreateFileTransfer(hContact, dwUin, nVersion); ft->dwCookie = dwCookie; ft->szFilename = mir_strdup(pszFileName); ft->szDescription = 0; ft->fileId = -1; ft->dwTotalSize = dwFileSize; ft->pMessage.dwMsgID1 = dwID1; ft->pMessage.dwMsgID2 = dwID2; ft->bDC = bDC; ft->bEmptyDesc = bEmptyDesc; // Send chain event TCHAR* ptszFileName = mir_utf8decodeT(pszFileName); PROTORECVFILET pre = {0}; pre.flags = PREF_TCHAR; pre.fileCount = 1; pre.timestamp = time(NULL); pre.tszDescription = mir_utf8decodeT(pszDescription); pre.ptszFiles = &ptszFileName; pre.lParam = (LPARAM)ft; ProtoChainRecvFile(hContact, &pre); mir_free(pre.tszDescription); mir_free(ptszFileName); }
void CIcqProto::parseStatusNote(DWORD dwUin, char *szUid, MCONTACT hContact, oscar_tlv_chain *pChain) { DWORD dwStatusNoteTS = time(NULL); BYTE *pStatusNoteTS, *pStatusNote; WORD wStatusNoteTSLen, wStatusNoteLen; BYTE bStatusNoteFlags; if (unpackSessionDataItem(pChain, 0x0D, &pStatusNoteTS, &wStatusNoteTSLen, NULL) && wStatusNoteTSLen == sizeof(DWORD)) unpackDWord(&pStatusNoteTS, &dwStatusNoteTS); // Get Status Note session item if (unpackSessionDataItem(pChain, 0x02, &pStatusNote, &wStatusNoteLen, &bStatusNoteFlags)) { char *szStatusNote = NULL; if ((bStatusNoteFlags & 4) == 4 && wStatusNoteLen >= 4) { BYTE *buf = pStatusNote; WORD buflen = wStatusNoteLen - 2; WORD wTextLen; unpackWord(&buf, &wTextLen); if (wTextLen > buflen) wTextLen = buflen; if (wTextLen > 0) { szStatusNote = (char*)_alloca(wStatusNoteLen + 1); unpackString(&buf, szStatusNote, wTextLen); szStatusNote[wTextLen] = '\0'; buflen -= wTextLen; WORD wEncodingType = 0; char *szEncoding = NULL; if (buflen >= 2) unpackWord(&buf, &wEncodingType); if (wEncodingType == 1 && buflen > 6) { // Encoding specified buf += 2; buflen -= 2; unpackWord(&buf, &wTextLen); if (wTextLen > buflen) wTextLen = buflen; szEncoding = (char*)_alloca(wTextLen + 1); unpackString(&buf, szEncoding, wTextLen); szEncoding[wTextLen] = '\0'; } else if (UTF8_IsValid(szStatusNote)) szEncoding = "utf-8"; szStatusNote = ApplyEncoding(szStatusNote, szEncoding); } } // Check if the status note was changed if (dwStatusNoteTS > getDword(hContact, DBSETTING_STATUS_NOTE_TIME, 0)) { DBVARIANT dbv = {DBVT_DELETED}; if (mir_strlen(szStatusNote) || (!getString(hContact, DBSETTING_STATUS_NOTE, &dbv) && (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8) && mir_strlen(dbv.pszVal))) debugLogA("%s changed status note to \"%s\"", strUID(dwUin, szUid), szStatusNote ? szStatusNote : ""); db_free(&dbv); if (szStatusNote) db_set_utf(hContact, m_szModuleName, DBSETTING_STATUS_NOTE, szStatusNote); else delSetting(hContact, DBSETTING_STATUS_NOTE); setDword(hContact, DBSETTING_STATUS_NOTE_TIME, dwStatusNoteTS); if (getContactXStatus(hContact) != 0 || !CheckContactCapabilities(hContact, CAPF_STATUS_MESSAGES)) { setStatusMsgVar(hContact, szStatusNote, false); TCHAR *tszNote = mir_utf8decodeT(szStatusNote); ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, NULL, (LPARAM)tszNote); mir_free(tszNote); } } SAFE_FREE(&szStatusNote); } else if (getContactStatus(hContact) == ID_STATUS_OFFLINE) { setStatusMsgVar(hContact, NULL, false); delSetting(hContact, DBSETTING_STATUS_NOTE); setDword(hContact, DBSETTING_STATUS_NOTE_TIME, dwStatusNoteTS); } }
void extractionMain( TMemoryStream &msf ) { const unsigned int MAX_ERRORS( 50 ); unsigned int items( 0 ); FILEINDEX_ENTRY info; unsigned char method; char *strMRFN( nullptr ), *strName( nullptr ); #define unpackString(buf,len) \ { \ buf = new char[ len +1 ]; \ msf.Read( buf, len ); \ buf[ len ] = 0; \ } #ifdef SAVE_MSF_FILEINDEX msf.SaveToFile("z3debug_fileindex.msf"); #endif // Are we just listing files? if( user_opt_list_files ) { std::string fname; printf("Listing filesystem contents\n\n"); while( msf.Position() < msf.Size() ) { method = msf.ReadByte(); msf.Read( &info, sizeof( FILEINDEX_ENTRY ) ); unpackString( strMRFN, info.lenMRFN ); unpackString( strName, info.lenName ); fname = fsRename( strMRFN, strName ); printf("%s\n", fname.c_str()); ++items; delete strMRFN; delete strName; } fname.clear(); printf("\nLocated %u files\n", items); } else // Run the main extraction loop { unsigned int errors( 0 ); printf("Extracting filesystem contents\n\n"); while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) ) { method = msf.ReadByte(); msf.Read( &info, sizeof( FILEINDEX_ENTRY ) ); unpackString( strMRFN, info.lenMRFN ); unpackString( strName, info.lenName ); if( !( extractItem( info, method, strMRFN, strName ) ) ) ++errors; ++items; delete strMRFN; delete strName; } if( errors >= MAX_ERRORS ) printf("ERROR: Extraction stopped as there were too many errors\n"); else printf("\nExtracted %u files (%u problems)\n", items, errors); } }
/*********************************************************************** * * INTERPRET_CHAR_PARAMETER * * For backwards compatibility, some matlab inputs are done with * character strings, such as using 'NC_CHAR' for a variable * declaration in DEF_VAR instead of nc_char. We have to be able to * handle that. This code is a clean implementation of the netcdf2 * routine "Parameter", which accomplished the same thing. * * Parameters: * mx: * matlab array that contains a character string * * Return Value: * If the parameter is identified, it is returned as an integer * value. Otherwise an exception is thrown. * **********************************************************************/ int interpret_char_parameter ( const mxArray *mx ) { /* * Define a datastructure to hold the enumerated constant and * the string equivalent. * */ typedef struct nc_constant_struct { int code; char *name; } nc_const; nc_const ncconst[] = { /* * Datatypes. * */ { NC_BYTE, "BYTE" }, { NC_CHAR, "CHAR" }, { NC_DOUBLE, "DOUBLE" }, { NC_FLOAT, "FLOAT" }, { NC_INT, "INT" }, { NC_LONG, "LONG" }, { NC_NAT, "NAT" }, { NC_SHORT, "SHORT" }, /* * Open and create modes. * */ { NC_CLOBBER, "CLOBBER" }, { NC_LOCK, "LOCK" }, { NC_NOCLOBBER, "NOCLOBBER" }, { NC_NOWRITE, "NOWRITE" }, { NC_SHARE, "SHARE" }, { NC_WRITE, "WRITE" }, { NC_64BIT_OFFSET, "64BIT_OFFSET" }, /* * Format modes. * */ { NC_FORMAT_CLASSIC, "FORMAT_CLASSIC" }, { NC_FORMAT_64BIT, "FORMAT_64BIT" }, /* * Error codes. * */ { NC_NOERR, "NOERR" }, { NC_EBADID, "EBADID" }, { NC_ENFILE, "ENFILE" }, { NC_EEXIST, "EEXIST" }, { NC_EINVAL, "EINVAL" }, { NC_EPERM, "EPERM" }, { NC_ENOTINDEFINE, "ENOTINDEFINE" }, { NC_EINDEFINE, "EINDEFINE" }, /* * -40 * */ { NC_EINVALCOORDS, "EINVALCOORDS" }, { NC_EMAXDIMS, "EMAXDIMS" }, { NC_ENAMEINUSE, "ENAMEINUSE" }, { NC_ENOTATT, "ENOTATT" }, { NC_EMAXATTS, "EMAXATTS" }, { NC_EBADTYPE, "EBADTYPE" }, { NC_EBADDIM, "EBADDIM" }, { NC_EUNLIMPOS, "EUNLIMPOS" }, { NC_EMAXVARS, "EMAXVARS" }, { NC_ENOTVAR, "ENOTVAR" }, /* * -50 * */ { NC_EGLOBAL, "EGLOBAL" }, { NC_ENOTNC, "ENOTNC" }, { NC_ESTS, "ESTS" }, { NC_EMAXNAME, "EMAXNAME" }, { NC_EUNLIMIT, "EUNLIMIT" }, { NC_ENORECVARS, "ENORECVARS" }, { NC_ECHAR, "ECHAR" }, { NC_EEDGE, "EEDGE" }, { NC_ESTRIDE, "ESTRIDE" }, { NC_EBADNAME, "EBADNAME" }, /* * -60 * */ { NC_ERANGE, "ERANGE" }, { NC_ENOMEM, "ENOMEM" }, { NC_EVARSIZE, "EVARSIZE" }, { NC_EDIMSIZE, "EDIMSIZE" }, { NC_FATAL, "FATAL" }, { NC_FILL, "FILL" }, { NC_GLOBAL, "GLOBAL" }, { NC_NOFILL, "NOFILL" }, { NC_UNLIMITED, "UNLIMITED" }, { NC_SIZEHINT_DEFAULT, "SIZEHINT_DEFAULT" }, { NC_VERBOSE, "VERBOSE" }, { 0, "NONE" } }; int parameter; /* * Character pointers for manipulating the parameter. * */ char *p, *q; /* * Loop index * */ int i; /* * flag as to whether or not we found the parameter in the * list of candidates. * */ int did_not_find_it; parameter = -1; p = unpackString ( mx ); /* * Make it upper case. * */ q = p; for (i = 0; i < strlen(p); i++) { *q = (char) toupper((int) *q); q++; } /* * Trim away any leading "NC_". * */ if (strncmp(p, "NC_", 3) == 0) { q = p + 3; } else { q = p; } /* * Loop thru the known parameter list. See if we can't identify * the parameter. * */ i = 0; did_not_find_it = 1; while (strcmp(ncconst[i].name, "NONE") != 0) { if (strcmp( q, ncconst[i].name ) == 0) { parameter = ncconst[i].code; did_not_find_it = 0; break; } else { i++; } } if ( did_not_find_it ) { sprintf ( error_message, "unable to identify parameter \"%s\"\n", p ); mexErrMsgTxt ( error_message ); } return (parameter); }