int MQTTClient_create(MQTTClient* handle, const char* serverURI, const char* clientId, int persistence_type, void* persistence_context) { int rc = 0; MQTTClients *m = NULL; FUNC_ENTRY; rc = Thread_lock_mutex(mqttclient_mutex); if (serverURI == NULL || clientId == NULL) { rc = MQTTCLIENT_NULL_PARAMETER; goto exit; } if (!UTF8_validateString(clientId)) { rc = MQTTCLIENT_BAD_UTF8_STRING; goto exit; } if (!initialized) { #if defined(HEAP_H) Heap_initialize(); #endif Log_initialize((Log_nameValue*)MQTTClient_getVersionInfo()); bstate->clients = ListInitialize(); Socket_outInitialize(); Socket_setWriteCompleteCallback(MQTTClient_writeComplete); handles = ListInitialize(); #if defined(OPENSSL) SSLSocket_initialize(); #endif initialized = 1; } m = malloc(sizeof(MQTTClients)); *handle = m; memset(m, '\0', sizeof(MQTTClients)); if (strncmp(URI_TCP, serverURI, strlen(URI_TCP)) == 0) serverURI += strlen(URI_TCP); #if defined(OPENSSL) else if (strncmp(URI_SSL, serverURI, strlen(URI_SSL)) == 0) { serverURI += strlen(URI_SSL); m->ssl = 1; } #endif m->serverURI = MQTTStrdup(serverURI); ListAppend(handles, m, sizeof(MQTTClients)); m->c = malloc(sizeof(Clients)); memset(m->c, '\0', sizeof(Clients)); m->c->context = m; m->c->outboundMsgs = ListInitialize(); m->c->inboundMsgs = ListInitialize(); m->c->messageQueue = ListInitialize(); m->c->clientID = MQTTStrdup(clientId); m->connect_sem = Thread_create_sem(); m->connack_sem = Thread_create_sem(); m->suback_sem = Thread_create_sem(); m->unsuback_sem = Thread_create_sem(); #if !defined(NO_PERSISTENCE) rc = MQTTPersistence_create(&(m->c->persistence), persistence_type, persistence_context); if (rc == 0) { rc = MQTTPersistence_initialize(m->c, m->serverURI); if (rc == 0) MQTTPersistence_restoreMessageQueue(m->c); } #endif ListAppend(bstate->clients, m->c, sizeof(Clients) + 3*sizeof(List)); exit: Thread_unlock_mutex(mqttclient_mutex); FUNC_EXIT_RC(rc); return rc; }
int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, int* qos) { MQTTClients* m = handle; List* topics = ListInitialize(); List* qoss = ListInitialize(); int i = 0; int rc = MQTTCLIENT_FAILURE; int msgid = 0; FUNC_ENTRY; Thread_lock_mutex(mqttclient_mutex); if (m == NULL || m->c == NULL) { rc = MQTTCLIENT_FAILURE; goto exit; } if (m->c->connected == 0) { rc = MQTTCLIENT_DISCONNECTED; goto exit; } for (i = 0; i < count; i++) { if (!UTF8_validateString(topic[i])) { rc = MQTTCLIENT_BAD_UTF8_STRING; goto exit; } if(qos[i] < 0 || qos[i] > 2) { rc = MQTTCLIENT_BAD_QOS; goto exit; } } if ((msgid = MQTTProtocol_assignMsgId(m->c)) == 0) { rc = MQTTCLIENT_MAX_MESSAGES_INFLIGHT; goto exit; } for (i = 0; i < count; i++) { ListAppend(topics, topic[i], strlen(topic[i])); ListAppend(qoss, &qos[i], sizeof(int)); } rc = MQTTProtocol_subscribe(m->c, topics, qoss, msgid); ListFreeNoContent(topics); ListFreeNoContent(qoss); if (rc == TCPSOCKET_COMPLETE) { MQTTPacket* pack = NULL; Thread_unlock_mutex(mqttclient_mutex); pack = MQTTClient_waitfor(handle, SUBACK, &rc, 10000L); Thread_lock_mutex(mqttclient_mutex); if (pack != NULL) { Suback* sub = (Suback*)pack; ListElement* current = NULL; i = 0; while (ListNextElement(sub->qoss, ¤t)) { int* reqqos = (int*)(current->content); qos[i++] = *reqqos; } rc = MQTTProtocol_handleSubacks(pack, m->c->net.socket); m->pack = NULL; } else rc = SOCKET_ERROR; } if (rc == SOCKET_ERROR) { Thread_unlock_mutex(mqttclient_mutex); MQTTClient_disconnect_internal(handle, 0); Thread_lock_mutex(mqttclient_mutex); } else if (rc == TCPSOCKET_COMPLETE) rc = MQTTCLIENT_SUCCESS; exit: Thread_unlock_mutex(mqttclient_mutex); FUNC_EXIT_RC(rc); return rc; }
int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char* const* topic) { MQTTClients* m = handle; List* topics = ListInitialize(); int i = 0; int rc = SOCKET_ERROR; int msgid = 0; FUNC_ENTRY; Thread_lock_mutex(mqttclient_mutex); if (m == NULL || m->c == NULL) { rc = MQTTCLIENT_FAILURE; goto exit; } if (m->c->connected == 0) { rc = MQTTCLIENT_DISCONNECTED; goto exit; } for (i = 0; i < count; i++) { if (!UTF8_validateString(topic[i])) { rc = MQTTCLIENT_BAD_UTF8_STRING; goto exit; } } if ((msgid = MQTTProtocol_assignMsgId(m->c)) == 0) { rc = MQTTCLIENT_MAX_MESSAGES_INFLIGHT; goto exit; } for (i = 0; i < count; i++) ListAppend(topics, topic[i], strlen(topic[i])); rc = MQTTProtocol_unsubscribe(m->c, topics, msgid); ListFreeNoContent(topics); if (rc == TCPSOCKET_COMPLETE) { MQTTPacket* pack = NULL; Thread_unlock_mutex(mqttclient_mutex); pack = MQTTClient_waitfor(handle, UNSUBACK, &rc, 10000L); Thread_lock_mutex(mqttclient_mutex); if (pack != NULL) { rc = MQTTProtocol_handleUnsubacks(pack, m->c->net.socket); m->pack = NULL; } else rc = SOCKET_ERROR; } if (rc == SOCKET_ERROR) { Thread_unlock_mutex(mqttclient_mutex); MQTTClient_disconnect_internal(handle, 0); Thread_lock_mutex(mqttclient_mutex); } exit: Thread_unlock_mutex(mqttclient_mutex); FUNC_EXIT_RC(rc); return rc; }
/** * Create a new socket and TCP connect to an address/port * @param addr the address string * @param port the TCP port * @param sock returns the new socket * @return completion code */ int Socket_new(char* addr, int port, int* sock) { int type = SOCK_STREAM; struct sockaddr_in address; #if defined(AF_INET6) struct sockaddr_in6 address6; #endif int rc = SOCKET_ERROR; #if defined(WIN32) || defined(WIN64) short family; #else sa_family_t family = AF_INET; #endif struct addrinfo *result = NULL; struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL, NULL}; FUNC_ENTRY; *sock = -1; if (addr[0] == '[') ++addr; if ((rc = getaddrinfo(addr, NULL, &hints, &result)) == 0) { struct addrinfo* res = result; /* prefer ip4 addresses */ while (res) { if (res->ai_family == AF_INET) { result = res; break; } res = res->ai_next; } if (result == NULL) rc = -1; else #if defined(AF_INET6) if (result->ai_family == AF_INET6) { address6.sin6_port = htons(port); address6.sin6_family = family = AF_INET6; address6.sin6_addr = ((struct sockaddr_in6*)(result->ai_addr))->sin6_addr; } else #endif if (result->ai_family == AF_INET) { address.sin_port = htons(port); address.sin_family = family = AF_INET; address.sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr; } else rc = -1; freeaddrinfo(result); } else Log(TRACE_MIN, -1, "getaddrinfo failed for addr %s with rc %d", addr, rc); if (rc != 0) Log(LOG_ERROR, -1, "%s is not a valid IP address", addr); else { *sock = socket(family, type, 0); if (*sock == INVALID_SOCKET) rc = Socket_error("socket", *sock); else { #if defined(NOSIGPIPE) int opt = 1; if (setsockopt(*sock, SOL_SOCKET, SO_NOSIGPIPE, (void*)&opt, sizeof(opt)) != 0) Log(TRACE_MIN, -1, "Could not set SO_NOSIGPIPE for socket %d", *sock); #endif Log(TRACE_MIN, -1, "New socket %d for %s, port %d", *sock, addr, port); if (Socket_addSocket(*sock) == SOCKET_ERROR) rc = Socket_error("setnonblocking", *sock); else { /* this could complete immmediately, even though we are non-blocking */ if (family == AF_INET) rc = connect(*sock, (struct sockaddr*)&address, sizeof(address)); #if defined(AF_INET6) else rc = connect(*sock, (struct sockaddr*)&address6, sizeof(address6)); #endif if (rc == SOCKET_ERROR) rc = Socket_error("connect", *sock); if (rc == EINPROGRESS || rc == EWOULDBLOCK) { int* pnewSd = (int*)malloc(sizeof(int)); *pnewSd = *sock; ListAppend(s.connect_pending, pnewSd, sizeof(int)); Log(TRACE_MIN, 15, "Connect pending"); } } } } FUNC_EXIT_RC(rc); return rc; }
SInt64 MqttServer::Run() { EventFlags events = this->GetEvents(); this->ForceSameThread(); // Http session is short connection, need to kill session when occur TimeoutEvent. // So return -1. if(events&Task::kTimeoutEvent || events&Task::kKillEvent) return -1; ZQ_Error err = ZQ_NoErr; while (this->IsLiveSession()) { // HTTP Session state machine. There are several well defined points in an HTTP request // where this session may have to return from its run function and wait for a new event. // Because of this, we need to track our current state and return to it. if(events&Task::kReadEvent) { if ((err = fInputStream.ReadRequest()) == ZQ_NoErr) { //+rt use the socket that reads the data, may be different now. fInputSocketP->RequestEvent(EV_RE); events -= Task::kReadEvent; continue; } if ((err != ZQ_RequestArrived) && (err != E2BIG)) { // Any other error implies that the client has gone away. At this point, // we can't have 2 sockets, so we don't need to do the "half closed" check // we do below Assert(err > 0); Assert(!this->IsLiveSession()); events -= Task::kReadEvent; break; } if (err == ZQ_RequestArrived) { char* pBuffer = fInputStream.GetRequestBuffer(); int nLen = fInputStream.GetRequsetLength(); ZQ_Error err = ZQ_NoErr; while(err == ZQ_NoErr && nLen > 0) { err = ProcessRecvMsg(pBuffer, nLen); } if(ZQ_NoErr == err) { err = fOutputStream.Flush(); if (err == EAGAIN) { UInt32 datalen = 0; char* pData = fOutputStream.GetBufferCopy(&datalen); if(pData) { OSMutexLocker locker(&fMutexList); ListAppend(&fMsgList, pData, datalen); } // If we get this error, we are currently flow-controlled and should // wait for the socket to become writeable again fSocket.RequestEvent(EV_RE | EV_WR); } } else { CleanupRequest(); } }; } else if(events&Task::kWriteEvent) { OSMutexLocker locker(&fMutexList); ListElement *elem = NULL; int theLengthSent = 0; if((elem = fMsgList.first) != NULL) { // err = fSocket.Send((const void*)elem->content, elem->size, &theLengthSent); if (err == EAGAIN) { fSocket.RequestEvent(EV_RE | EV_WR); } else { ListRemoveHead(&fMsgList); if(NULL != fMsgList.first) this->Signal(kWriteEvent); } } events -= Task::kWriteEvent; } else if(events&Task::kZmqEvent) { events -= Task::kZmqEvent; } else { return 0; } } // Make absolutely sure there are no resources being occupied by the session // at this point. this->CleanupRequest(); // Only delete if it is ok to delete! if (fObjectHolders == 0) return -1; // If we are here because of a timeout, but we can't delete because someone // is holding onto a reference to this session, just reschedule the timeout. // // At this point, however, the session is DEAD. return 0; }
/** * Originates a new publication - sends it to all clients subscribed. * @param publish pointer to a stucture which contains all the publication information * @param originator the originating client */ void Protocol_processPublication(Publish* publish, char* originator) { Messages* stored = NULL; /* to avoid duplication of data where possible */ List* clients; ListElement* current = NULL; int savedMsgId = publish->msgId; int clean_needed = 0; FUNC_ENTRY; if (Topics_hasWildcards(publish->topic)) { Log(LOG_INFO, 12, NULL, publish->topic, originator); goto exit; } if ((strcmp(INTERNAL_CLIENTID, originator) != 0) && bstate->password_file && bstate->acl_file) { Clients* client = (Clients*)(TreeFindIndex(bstate->clients, originator, 1)->content); if (Users_authorise(client->user, publish->topic, ACL_WRITE) == false) { Log(LOG_AUDIT, 149, NULL, originator, publish->topic); goto exit; } } if (publish->header.bits.retain) { SubscriptionEngines_setRetained(bstate->se, publish->topic, publish->header.bits.qos, publish->payload, publish->payloadlen); if (bstate->persistence == 1 && bstate->autosave_on_changes == 1 && bstate->autosave_interval > 0 && bstate->se->retained_changes >= bstate->autosave_interval) { Log(LOG_INFO, 100, NULL, bstate->autosave_interval); SubscriptionEngines_save(bstate->se); } } clients = SubscriptionEngines_getSubscribers(bstate->se, publish->topic, originator); if (strncmp(publish->topic, "$SYS/client/", 12) == 0) { /* default subscription for a client */ Node* node = TreeFindIndex(bstate->clients, &publish->topic[12], 1); if (node == NULL) node = TreeFind(bstate->disconnected_clients, &publish->topic[12]); if (node && node->content) { Subscriptions* rcs = malloc(sizeof(Subscriptions)); rcs->clientName = &publish->topic[12]; rcs->qos = 2; rcs->priority = PRIORITY_NORMAL; rcs->topicName = publish->topic; ListAppend(clients, rcs, sizeof(Subscriptions)); } } current = NULL; while (ListNextElement(clients, ¤t)) { Node* curnode = NULL; unsigned int qos = ((Subscriptions*)(current->content))->qos; int priority = ((Subscriptions*)(current->content))->priority; char* clientName = ((Subscriptions*)(current->content))->clientName; if (publish->header.bits.qos < qos) /* reduce qos if > subscribed qos */ qos = publish->header.bits.qos; if ((curnode = TreeFindIndex(bstate->clients, clientName, 1)) == NULL) curnode = TreeFind(bstate->disconnected_clients, clientName); #if defined(MQTTS) if (curnode == NULL && ((curnode = TreeFindIndex(bstate->mqtts_clients, clientName, 1)) == NULL)) curnode = TreeFind(bstate->disconnected_mqtts_clients, clientName); #endif if (curnode) { Clients* pubclient = (Clients*)(curnode->content); int retained = 0; Messages* saved = NULL; char* original_topic = publish->topic; #if !defined(NO_BRIDGE) if (pubclient->outbound || pubclient->noLocal) { retained = publish->header.bits.retain; /* outbound and noLocal mean outward/inward bridge client, so keep retained flag */ if (pubclient->outbound) { Bridge_handleOutbound(pubclient, publish); if (publish->topic != original_topic) { /* handleOutbound has changed the topic, so we musn't used the stored pub which contains the original topic */ saved = stored; stored = NULL; } } } #endif if (Protocol_startOrQueuePublish(pubclient, publish, qos, retained, priority, &stored) == SOCKET_ERROR) { pubclient->good = pubclient->connected = 0; /* flag this client as needing to be cleaned up */ clean_needed = 1; } if (publish->topic != original_topic) { stored = saved; /* restore the stored pointer for the next loop iteration */ free(publish->topic); publish->topic = original_topic; } } } publish->msgId = savedMsgId; /* INTERNAL_CLIENTID means that we are publishing data to the log, and we don't want to interfere with other close processing */ if (clean_needed && strcmp(originator, INTERNAL_CLIENTID) != 0) MQTTProtocol_clean_clients(bstate->clients); ListFree(clients); exit: FUNC_EXIT; }
/** * Create the server socket in multi-listener mode. * @param list pointer to a listener structure * @return completion code */ int Socket_addServerSocket(Listener* list) { int flag = 1; int rc = SOCKET_ERROR; int ipv4 = 1; /* yes we can drop down to ipv4 */ FUNC_ENTRY; if (!list->address || strcmp(list->address, "INADDR_ANY") == 0) { struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; list->addr.sin_addr.s_addr = htonl(INADDR_ANY); list->addr6.sin6_addr = in6addr_any; } else { if (list->address[0] == '[') { int changed = ipv6_format(list->address); #if defined(WIN32) /*wchar_t buf[(INET6_ADDRSTRLEN+1)*2]; int buflen = sizeof(list->addr6); mbstowcs(buf, &list->address[1], sizeof(buf)); rc = WSAStringToAddress(buf, AF_INET6, NULL, (struct sockaddr*)&list->addr6, &buflen);*/ rc = win_inet_pton(AF_INET6, &list->address[1], &(list->addr6.sin6_addr)); #else rc = inet_pton(AF_INET6, &list->address[1], &(list->addr6.sin6_addr)); #endif ipv4 = 0; if (changed) (list->address)[changed] = ']'; } else { #if defined(WIN32) /*wchar_t buf[(INET6_ADDRSTRLEN+1)*2]; int buflen = sizeof(list->addr); mbstowcs(buf, list->address, sizeof(buf)); rc = WSAStringToAddress(buf, AF_INET, NULL, (struct sockaddr*)&list->addr, &buflen);*/ rc = win_inet_pton(AF_INET, list->address, &(list->addr.sin_addr.s_addr)); #else rc = inet_pton(AF_INET, list->address, &(list->addr.sin_addr.s_addr)); #endif list->ipv6 = 0; } #if defined(WIN32) if (rc != 0) #else if (rc != 1) #endif { Log(LOG_WARNING, 67, NULL, list->address); rc = -1; goto exit; } } list->socket = -1; if (list->protocol == PROTOCOL_MQTT) { if (list->ipv6) list->socket = socket(AF_INET6, SOCK_STREAM, 0); if (list->socket < 0 && ipv4) { list->socket = socket(AF_INET, SOCK_STREAM, 0); list->ipv6 = 0; } } #if defined(MQTTS) else if (list->protocol == PROTOCOL_MQTTS) { if (list->ipv6) list->socket = socket(AF_INET6, SOCK_DGRAM, 0); if (list->socket < 0 && ipv4) { list->socket = socket(AF_INET, SOCK_DGRAM, 0); list->ipv6 = 0; } } #endif Log(TRACE_MAX, 6, NULL, FD_SETSIZE); if (list->socket < 0) { Socket_error("socket", list->socket); Log(LOG_WARNING, 77, NULL); rc = list->socket; goto exit; } #if !defined(WIN32) if (setsockopt(list->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&flag, sizeof(int)) != 0) Log(LOG_WARNING, 109, NULL, list->port); #endif if (list->ipv6) { list->addr6.sin6_family = AF_INET6; list->addr6.sin6_port = htons(list->port); rc = bind(list->socket, (struct sockaddr *)&(list->addr6), sizeof(list->addr6)); } else { list->addr.sin_family = AF_INET; list->addr.sin_port = htons(list->port); memset(list->addr.sin_zero, 0, sizeof(list->addr.sin_zero)); rc = bind(list->socket, (struct sockaddr *)&(list->addr), sizeof(list->addr)); } if (rc == SOCKET_ERROR) { Socket_error("bind", list->socket); Log(LOG_WARNING, 78, NULL, list->port); goto exit; } /* Only listen if this is mqtt/tcp */ if (list->protocol == PROTOCOL_MQTT && listen(list->socket, SOMAXCONN) == SOCKET_ERROR) /* second parm is max no of connections */ { Socket_error("listen", list->socket); Log(LOG_WARNING, 79, NULL, list->port); goto exit; } if (Socket_setnonblocking(list->socket) == SOCKET_ERROR) { Socket_error("setnonblocking", list->socket); goto exit; } #if defined(MQTTS) /* If mqtts/udp, add to the list of clientsds to test for reading */ if (list->protocol == PROTOCOL_MQTTS) { ListElement* current = NULL; int loopback = list->loopback; #if !defined(USE_POLL) int* pnewSd = (int*)malloc(sizeof(list->socket)); *pnewSd = list->socket; ListAppend(s.clientsds, pnewSd, sizeof(list->socket)); #endif Log(LOG_INFO, 300, NULL, list->port); if (setsockopt(list->socket, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback, sizeof(loopback)) == SOCKET_ERROR) Socket_error("set listener IP_MULTICAST_LOOP", list->socket); /* join any multicast groups */ while (ListNextElement(list->multicast_groups, ¤t)) Socket_joinMulticastGroup(list->socket, list->ipv6, (char*)(current->content)); } else #endif Log(LOG_INFO, 14, NULL, list->port); #if defined(USE_POLL) /* add new socket to the epoll descriptor with epoll_ctl */ struct socket_info* si = malloc(sizeof(struct socket_info)); si->listener = list; si->fd = list->socket; si->connect_pending = 0; si->event.events = EPOLLIN; si->event.data.ptr = si; TreeAdd(s.fds_tree, si, sizeof(struct socket_info)); if (epoll_ctl(s.epoll_fds, EPOLL_CTL_ADD, list->socket, &si->event) != 0) Socket_error("epoll_ctl add", list->socket); #else FD_SET((u_int)list->socket, &(s.rset)); /* Add the current socket descriptor */ s.maxfdp1 = max(s.maxfdp1+1, list->socket+1); memcpy((void*)&(s.rset_saved), (void*)&(s.rset), sizeof(s.rset_saved)); #endif rc = 0; exit: FUNC_EXIT_RC(rc); return rc; }
int MQTTClient_create(MQTTClient* handle, char* serverURI, char* clientId, int persistence_type, void* persistence_context) { int rc = 0; MQTTClients *m = NULL; FUNC_ENTRY; rc = Thread_lock_mutex(mqttclient_mutex); if (serverURI == NULL || clientId == NULL) { rc = MQTTCLIENT_NULL_PARAMETER; goto exit; } if (!UTF8_validateString(clientId)) { rc = MQTTCLIENT_BAD_UTF8_STRING; goto exit; } if (!initialized) { #if defined(HEAP_H) Heap_initialize(); #endif Log_initialize(); bstate->clients = ListInitialize(); Socket_outInitialize(); handles = ListInitialize(); initialized = 1; } m = malloc(sizeof(MQTTClients)); *handle = m; memset(m, '\0', sizeof(MQTTClients)); if (strncmp(URI_TCP, serverURI, strlen(URI_TCP)) == 0) serverURI += strlen(URI_TCP); m->serverURI = malloc(strlen(serverURI)+1); strcpy(m->serverURI, serverURI); ListAppend(handles, m, sizeof(MQTTClients)); m->c = malloc(sizeof(Clients)); memset(m->c, '\0', sizeof(Clients)); m->c->outboundMsgs = ListInitialize(); m->c->inboundMsgs = ListInitialize(); m->c->messageQueue = ListInitialize(); m->c->clientID = malloc(strlen(clientId)+1); strcpy(m->c->clientID, clientId); m->connect_sem = Thread_create_sem(); m->connack_sem = Thread_create_sem(); m->suback_sem = Thread_create_sem(); m->unsuback_sem = Thread_create_sem(); #if !defined(NO_PERSISTENCE) rc = MQTTPersistence_create(&(m->c->persistence), persistence_type, persistence_context); if (rc == 0) rc = MQTTPersistence_initialize(m->c, m->serverURI); #endif ListAppend(bstate->clients, m->c, sizeof(Clients) + 3*sizeof(List)); exit: if (Thread_unlock_mutex(mqttclient_mutex) != 0) /* FFDC? */; FUNC_EXIT_RC(rc); return rc; }
int MQTTClient_subscribeMany(MQTTClient handle, int count, char** topic, int* qos) { MQTTClients* m = handle; List* topics = ListInitialize(); List* qoss = ListInitialize(); int i = 0; int rc = MQTTCLIENT_FAILURE; FUNC_ENTRY; Thread_lock_mutex(mqttclient_mutex); if (m == NULL || m->c == NULL) { rc = MQTTCLIENT_FAILURE; goto exit; } if (m->c->connected == 0) { rc = MQTTCLIENT_DISCONNECTED; goto exit; } for (i = 0; i < count; i++) { if (!UTF8_validateString(topic[i])) { rc = MQTTCLIENT_BAD_UTF8_STRING; goto exit; } } for (i = 0; i < count; i++) { ListAppend(topics, topic[i], strlen(topic[i])); ListAppend(qoss, &qos[i], sizeof(int)); } rc = MQTTProtocol_subscribe(m->c, topics, qoss); ListFreeNoContent(topics); ListFreeNoContent(qoss); if (rc == TCPSOCKET_COMPLETE) { MQTTPacket* pack = NULL; Thread_unlock_mutex(mqttclient_mutex); pack = MQTTClient_waitfor(handle, SUBACK, &rc, 10000L); Thread_lock_mutex(mqttclient_mutex); if (pack != NULL) { rc = MQTTProtocol_handleSubacks(pack, m->c->socket); m->pack = NULL; } else rc = SOCKET_ERROR; } if (rc == SOCKET_ERROR) { Thread_unlock_mutex(mqttclient_mutex); MQTTClient_disconnect_internal(handle, 0); Thread_lock_mutex(mqttclient_mutex); } else if (rc == TCPSOCKET_COMPLETE) rc = MQTTCLIENT_SUCCESS; exit: Thread_unlock_mutex(mqttclient_mutex); FUNC_EXIT_RC(rc); return rc; }
static void AssignOpcodes(FILE *f) { List *group1 = ListAppend(NULL, 0); int i; for (i = 1; i < N1; i++) ListAppend(group1, i); ADD2 = PopRandomOpcode1(&group1); ADD4 = PopRandomOpcode1(&group1); ADDC2 = PopRandomOpcode1(&group1); ADDC4 = PopRandomOpcode1(&group1); ANL2 = PopRandomOpcode1(&group1); ANL4 = PopRandomOpcode1(&group1); ANL5 = PopRandomOpcode1(&group1); ANL6 = PopRandomOpcode1(&group1); ANL7 = PopRandomOpcode1(&group1); ANL8 = PopRandomOpcode1(&group1); CJNE1 = PopRandomOpcode1(&group1); CJNE2 = PopRandomOpcode1(&group1); CLR1 = PopRandomOpcode1(&group1); CLR2 = PopRandomOpcode1(&group1); CLR3 = PopRandomOpcode1(&group1); CPL1 = PopRandomOpcode1(&group1); CPL2 = PopRandomOpcode1(&group1); CPL3 = PopRandomOpcode1(&group1); DA = PopRandomOpcode1(&group1); DEC1 = PopRandomOpcode1(&group1); DEC3 = PopRandomOpcode1(&group1); DIV = PopRandomOpcode1(&group1); DJNZ2 = PopRandomOpcode1(&group1); INC1 = PopRandomOpcode1(&group1); INC3 = PopRandomOpcode1(&group1); INC5 = PopRandomOpcode1(&group1); JB = PopRandomOpcode1(&group1); JBC = PopRandomOpcode1(&group1); JC = PopRandomOpcode1(&group1); JMP = PopRandomOpcode1(&group1); JNB = PopRandomOpcode1(&group1); JNC = PopRandomOpcode1(&group1); JNZ = PopRandomOpcode1(&group1); JZ = PopRandomOpcode1(&group1); LCALL = PopRandomOpcode1(&group1); LJMP = PopRandomOpcode1(&group1); MOV2 = PopRandomOpcode1(&group1); MOV4 = PopRandomOpcode1(&group1); MOV8 = PopRandomOpcode1(&group1); MOV10 = PopRandomOpcode1(&group1); MOV12 = PopRandomOpcode1(&group1); MOV16 = PopRandomOpcode1(&group1); MOV17 = PopRandomOpcode1(&group1); MOV18 = PopRandomOpcode1(&group1); MOVC1 = PopRandomOpcode1(&group1); MOVC2 = PopRandomOpcode1(&group1); MOVX2 = PopRandomOpcode1(&group1); MOVX4 = PopRandomOpcode1(&group1); MUL = PopRandomOpcode1(&group1); ORL2 = PopRandomOpcode1(&group1); ORL4 = PopRandomOpcode1(&group1); ORL5 = PopRandomOpcode1(&group1); ORL6 = PopRandomOpcode1(&group1); ORL7 = PopRandomOpcode1(&group1); ORL8 = PopRandomOpcode1(&group1); POP = PopRandomOpcode1(&group1); PUSH = PopRandomOpcode1(&group1); RET = PopRandomOpcode1(&group1); RL = PopRandomOpcode1(&group1); RLC = PopRandomOpcode1(&group1); RR = PopRandomOpcode1(&group1); RRC = PopRandomOpcode1(&group1); SETB1 = PopRandomOpcode1(&group1); SETB2 = PopRandomOpcode1(&group1); SJMP = PopRandomOpcode1(&group1); SUBB2 = PopRandomOpcode1(&group1); SUBB4 = PopRandomOpcode1(&group1); SWAP = PopRandomOpcode1(&group1); XCH2 = PopRandomOpcode1(&group1); XRL2 = PopRandomOpcode1(&group1); XRL4 = PopRandomOpcode1(&group1); XRL5 = PopRandomOpcode1(&group1); XRL6 = PopRandomOpcode1(&group1); group1 = ListAppend(NULL, 0); for (i = 1; i < N2; i++) ListAppend(group1, i); ADD3 = PopRandomOpcode2(&group1); ADDC3 = PopRandomOpcode2(&group1); ANL3 = PopRandomOpcode2(&group1); CJNE4 = PopRandomOpcode2(&group1); DEC4 = PopRandomOpcode2(&group1); INC4 = PopRandomOpcode2(&group1); MOV3 = PopRandomOpcode2(&group1); MOV11 = PopRandomOpcode2(&group1); MOV13 = PopRandomOpcode2(&group1); MOV14 = PopRandomOpcode2(&group1); MOV15 = PopRandomOpcode2(&group1); MOVX1 = PopRandomOpcode2(&group1); MOVX3 = PopRandomOpcode2(&group1); ORL3 = PopRandomOpcode2(&group1); SUBB3 = PopRandomOpcode2(&group1); XCH3 = PopRandomOpcode2(&group1); XCHD = PopRandomOpcode2(&group1); XRL3 = PopRandomOpcode2(&group1); group1 = ListAppend(NULL, 0); for (i = 1; i < N3; i++) ListAppend(group1, i); ADD1 = PopRandomOpcode3(&group1); ADDC1 = PopRandomOpcode3(&group1); ANL1 = PopRandomOpcode3(&group1); CJNE3 = PopRandomOpcode3(&group1); DEC2 = PopRandomOpcode3(&group1); DJNZ1 = PopRandomOpcode3(&group1); INC2 = PopRandomOpcode3(&group1); MOV1 = PopRandomOpcode3(&group1); MOV5 = PopRandomOpcode3(&group1); MOV6 = PopRandomOpcode3(&group1); MOV7 = PopRandomOpcode3(&group1); MOV9 = PopRandomOpcode3(&group1); ORL1 = PopRandomOpcode3(&group1); SUBB1 = PopRandomOpcode3(&group1); XRL1 = PopRandomOpcode3(&group1); XCH1 = PopRandomOpcode3(&group1); group1 = ListAppend(NULL, 0); for (i = 1; i < N4; i++) ListAppend(group1, i); ACALL = PopRandomOpcode4(&group1); AJMP = PopRandomOpcode4(&group1); ANL2_X = rand(); ANL4_X = rand(); ANL5_X = rand(); ANL6_X1 = rand(); ANL6_X2 = rand(); ANL7_X = rand(); ANL8_X = rand(); ORL2_X = rand(); ORL4_X = rand(); ORL5_X = rand(); ORL6_X1 = rand(); ORL6_X2 = rand(); ORL7_X = rand(); ORL8_X = rand(); XRL2_X = rand(); XRL4_X = rand(); XRL5_X = rand(); XRL6_X1 = rand(); XRL6_X2 = rand(); CLR3_X = rand(); SETB2_X = rand(); CPL3_X = rand(); XCH2_X = rand(); LCALL_X1 = rand(); LCALL_X2 = rand(); ACALL_X = rand(); CJNE1_X1 = rand(); CJNE1_X2 = rand(); CJNE2_X1 = rand(); CJNE2_X2 = rand(); CJNE3_X1 = rand(); CJNE3_X2 = rand(); CJNE4_X1 = rand(); CJNE4_X2 = rand(); DEC3_X = rand(); INC3_X = rand(); DJNZ1_X = rand(); DJNZ2_X1 = rand(); DJNZ2_X2 = rand(); POP_X = rand(); PUSH_X = rand(); JB_X1 = rand(); JB_X2 = rand(); JBC_X1 = rand(); JBC_X2 = rand(); JC_X = rand(); JNB_X1 = rand(); JNB_X2 = rand(); JNC_X = rand(); JNZ_X = rand(); JZ_X = rand(); AJMP_X = rand(); LJMP_X1 = rand(); LJMP_X2 = rand(); SJMP_X = rand(); MOV2_X = rand(); MOV4_X = rand(); MOV6_X = rand(); MOV7_X = rand(); MOV8_X = rand(); MOV9_X = rand(); MOV10_X1 = rand(); MOV10_X2 = rand(); MOV11_X = rand(); MOV12_X1 = rand(); MOV12_X2 = rand(); MOV14_X = rand(); MOV15_X = rand(); MOV16_X = rand(); MOV17_X = rand(); MOV18_X1 = rand(); MOV18_X2 = rand(); ADD2_X = rand(); ADD4_X = rand(); ADDC2_X = rand(); ADDC4_X = rand(); SUBB2_X = rand(); SUBB4_X = rand(); group1 = ListAppend2(NULL, ADD2, "ADD2"); ListAppend2(group1, ADD4, "ADD4"); ListAppend2(group1, ADDC2, "ADDC2"); ListAppend2(group1, ADDC4, "ADDC4"); ListAppend2(group1, ANL2, "ANL2"); ListAppend2(group1, ANL4, "ANL4"); ListAppend2(group1, ANL5, "ANL5"); ListAppend2(group1, ANL6, "ANL6"); ListAppend2(group1, ANL7, "ANL7"); ListAppend2(group1, ANL8, "ANL8"); ListAppend2(group1, CJNE1, "CJNE1"); ListAppend2(group1, CJNE2, "CJNE2"); ListAppend2(group1, CLR1, "CLR1"); ListAppend2(group1, CLR2, "CLR2"); ListAppend2(group1, CLR3, "CLR3"); ListAppend2(group1, CPL1, "CPL1"); ListAppend2(group1, CPL2, "CPL2"); ListAppend2(group1, CPL3, "CPL3"); ListAppend2(group1, DA, "DA"); ListAppend2(group1, DEC1, "DEC1"); ListAppend2(group1, DEC3, "DEC3"); ListAppend2(group1, DIV, "DIV"); ListAppend2(group1, DJNZ2, "DJNZ2"); ListAppend2(group1, INC1, "INC1"); ListAppend2(group1, INC3, "INC3"); ListAppend2(group1, INC5, "INC5"); ListAppend2(group1, JB, "JB"); ListAppend2(group1, JBC, "JBC"); ListAppend2(group1, JC, "JC"); ListAppend2(group1, JMP, "JMP"); ListAppend2(group1, JNB, "JNB"); ListAppend2(group1, JNC, "JNC"); ListAppend2(group1, JNZ, "JNZ"); ListAppend2(group1, JZ, "JZ"); ListAppend2(group1, LCALL, "LCALL"); ListAppend2(group1, LJMP, "LJMP"); ListAppend2(group1, MOV2, "MOV2"); ListAppend2(group1, MOV4, "MOV4"); ListAppend2(group1, MOV8, "MOV8"); ListAppend2(group1, MOV10, "MOV10"); ListAppend2(group1, MOV12, "MOV12"); ListAppend2(group1, MOV16, "MOV16"); ListAppend2(group1, MOV17, "MOV17"); ListAppend2(group1, MOV18, "MOV18"); ListAppend2(group1, MOVC1, "MOVC1"); ListAppend2(group1, MOVC2, "MOVC2"); ListAppend2(group1, MOVX2, "MOVX2"); ListAppend2(group1, MOVX4, "MOVX4"); ListAppend2(group1, MUL, "MUL"); ListAppend2(group1, ORL2, "ORL2"); ListAppend2(group1, ORL4, "ORL4"); ListAppend2(group1, ORL5, "ORL5"); ListAppend2(group1, ORL6, "ORL6"); ListAppend2(group1, ORL7, "ORL7"); ListAppend2(group1, ORL8, "ORL8"); ListAppend2(group1, POP, "POP"); ListAppend2(group1, PUSH, "PUSH"); ListAppend2(group1, RET, "RET"); ListAppend2(group1, RL, "RL"); ListAppend2(group1, RLC, "RLC"); ListAppend2(group1, RR, "RR"); ListAppend2(group1, RRC, "RRC"); ListAppend2(group1, SETB1, "SETB1"); ListAppend2(group1, SETB2, "SETB2"); ListAppend2(group1, SJMP, "SJMP"); ListAppend2(group1, SUBB2, "SUBB2"); ListAppend2(group1, SUBB4, "SUBB4"); ListAppend2(group1, SWAP, "SWAP"); ListAppend2(group1, XCH2, "XCH2"); ListAppend2(group1, XRL2, "XRL2"); ListAppend2(group1, XRL4, "XRL4"); ListAppend2(group1, XRL5, "XRL5"); ListAppend2(group1, XRL6, "XRL6"); ListAppend2(group1, ADD3, "ADD3"); ListAppend2(group1, ADDC3, "ADDC3"); ListAppend2(group1, ANL3, "ANL3"); ListAppend2(group1, CJNE4, "CJNE4"); ListAppend2(group1, DEC4, "DEC4"); ListAppend2(group1, INC4, "INC4"); ListAppend2(group1, MOV3, "MOV3"); ListAppend2(group1, MOV11, "MOV11"); ListAppend2(group1, MOV13, "MOV13"); ListAppend2(group1, MOV14, "MOV14"); ListAppend2(group1, MOV15, "MOV15"); ListAppend2(group1, MOVX1, "MOVX1"); ListAppend2(group1, MOVX3, "MOVX3"); ListAppend2(group1, ORL3, "ORL3"); ListAppend2(group1, SUBB3, "SUBB3"); ListAppend2(group1, XCH3, "XCH3"); ListAppend2(group1, XCHD, "XCHD"); ListAppend2(group1, XRL3, "XRL3"); ListAppend2(group1, ADD1, "ADD1"); ListAppend2(group1, ADDC1, "ADDC1"); ListAppend2(group1, ANL1, "ANL1"); ListAppend2(group1, CJNE3, "CJNE3"); ListAppend2(group1, DEC2, "DEC2"); ListAppend2(group1, DJNZ1, "DJNZ1"); ListAppend2(group1, INC2, "INC2"); ListAppend2(group1, MOV1, "MOV1"); ListAppend2(group1, MOV5, "MOV5"); ListAppend2(group1, MOV6, "MOV6"); ListAppend2(group1, MOV7, "MOV7"); ListAppend2(group1, MOV9, "MOV9"); ListAppend2(group1, ORL1, "ORL1"); ListAppend2(group1, SUBB1, "SUBB1"); ListAppend2(group1, XRL1, "XRL1"); ListAppend2(group1, XCH1, "XCH1"); ListAppend2(group1, ACALL, "ACALL"); ListAppend2(group1, AJMP, "AJMP"); ListAppend2(group1, ANL2_X, "ANL2_X"); ListAppend2(group1, ANL4_X, "ANL4_X"); ListAppend2(group1, ANL5_X, "ANL5_X"); ListAppend2(group1, ANL6_X1, "ANL6_X1"); ListAppend2(group1, ANL6_X2, "ANL6_X2"); ListAppend2(group1, ANL7_X, "ANL7_X"); ListAppend2(group1, ANL8_X, "ANL8_X"); ListAppend2(group1, ORL2_X, "ORL2_X"); ListAppend2(group1, ORL4_X, "ORL4_X"); ListAppend2(group1, ORL5_X, "ORL5_X"); ListAppend2(group1, ORL6_X1,"ORL6_X1"); ListAppend2(group1, ORL6_X2, "ORL6_X2"); ListAppend2(group1, ORL7_X, "ORL7_X"); ListAppend2(group1, ORL8_X, "ORL8_X"); ListAppend2(group1, XRL2_X, "XRL2_X"); ListAppend2(group1, XRL4_X, "XRL4_X"); ListAppend2(group1, XRL5_X, "XRL5_X"); ListAppend2(group1, XRL6_X1, "XRL6_X1"); ListAppend2(group1, XRL6_X2, "XRL6_X2"); ListAppend2(group1, CLR3_X, "CLR3_X"); ListAppend2(group1, SETB2_X, "SETB2_X"); ListAppend2(group1, CPL3_X, "CPL3_X"); ListAppend2(group1, XCH2_X, "XCH2_X"); ListAppend2(group1, LCALL_X1, "LCALL_X1"); ListAppend2(group1, LCALL_X2, "LCALL_X2"); ListAppend2(group1, ACALL_X, "ACALL_X"); ListAppend2(group1, CJNE1_X1, "CJNE1_X1"); ListAppend2(group1, CJNE1_X2, "CJNE1_X2"); ListAppend2(group1, CJNE2_X1, "CJNE2_X1"); ListAppend2(group1, CJNE2_X2, "CJNE2_X2"); ListAppend2(group1, CJNE3_X1, "CJNE3_X1"); ListAppend2(group1, CJNE3_X2, "CJNE3_X2"); ListAppend2(group1, CJNE4_X1, "CJNE4_X1"); ListAppend2(group1, CJNE4_X2, "CJNE4_X2"); ListAppend2(group1, DEC3_X, "DEC3_X"); ListAppend2(group1, INC3_X, "INC3_X"); ListAppend2(group1, DJNZ1_X, "DJNZ1_X"); ListAppend2(group1, DJNZ2_X1, "DJNZ2_X1"); ListAppend2(group1, DJNZ2_X2, "DJNZ2_X2"); ListAppend2(group1, POP_X, "POP_X"); ListAppend2(group1, PUSH_X, "PUSH_X"); ListAppend2(group1, JB_X1, "JB_X1"); ListAppend2(group1, JB_X2, "JB_X2"); ListAppend2(group1, JBC_X1, "JBC_X1"); ListAppend2(group1, JBC_X2, "JBC_X2"); ListAppend2(group1, JC_X, "JC_X"); ListAppend2(group1, JNB_X1, "JNB_X1"); ListAppend2(group1, JNB_X2, "JNB_X2"); ListAppend2(group1, JNC_X, "JNC_X"); ListAppend2(group1, JNZ_X, "JNZ_X"); ListAppend2(group1, JZ_X, "JZ_X"); ListAppend2(group1, AJMP_X, "AJMP_X"); ListAppend2(group1, LJMP_X1, "LJMP_X1"); ListAppend2(group1, LJMP_X2, "LJMP_X2"); ListAppend2(group1, SJMP_X, "SJMP_X"); ListAppend2(group1, MOV2_X, "MOV2_X"); ListAppend2(group1, MOV4_X, "MOV4_X"); ListAppend2(group1, MOV6_X, "MOV6_X"); ListAppend2(group1, MOV7_X, "MOV7_X"); ListAppend2(group1, MOV8_X, "MOV8_X"); ListAppend2(group1, MOV9_X, "MOV9_X"); ListAppend2(group1, MOV10_X1, "MOV10_X1"); ListAppend2(group1, MOV10_X2, "MOV10_X2"); ListAppend2(group1, MOV11_X, "MOV11_X"); ListAppend2(group1, MOV12_X1, "MOV12_X1"); ListAppend2(group1, MOV12_X2, "MOV12_X2"); ListAppend2(group1, MOV14_X, "MOV14_X"); ListAppend2(group1, MOV15_X, "MOV15_X"); ListAppend2(group1, MOV16_X, "MOV16_X"); ListAppend2(group1, MOV17_X, "MOV17_X"); ListAppend2(group1, MOV18_X1, "MOV18_X1"); ListAppend2(group1, MOV18_X2, "MOV18_X2"); ListAppend2(group1, ADD2_X, "ADD2_X"); ListAppend2(group1, ADD4_X, "ADD4_X"); ListAppend2(group1, ADDC2_X, "ADDC2_X"); ListAppend2(group1, ADDC4_X, "ADDC4_X"); ListAppend2(group1, SUBB2_X, "SUBB2_X"); ListAppend2(group1, SUBB4_X, "SUBB4_X"); int n = GetListLength(group1); for (i = 0; i < n; i++) { uint8_t opcode; const char *name = PopRandomOpcode(&group1, &opcode); fprintf(f, "static uint8_t %s = 0x%02X;\n", name, opcode); } }
void *YAsyncBytes(long n) { void *ptr= p_malloc(n); return keeplist? ListAppend(ptr) : ptr; }
int InvokeProgram(int oftype) { List p = NULL; char **cmd; char *file; int status = 0; switch (oftype) { case PP_FILE: if (Option.cfiles == NULL) return 0; for (p = Option.cfiles; p != NULL; p = p->next) { PPFiles = ListAppend(PPFiles, FileName(p->str, ".i")); } Option.pfiles = ListCombine(Option.pfiles, PPFiles); cmd = BuildCommand(CPPProg, Option.pflags, Option.cfiles, PPFiles); status = _spawnvp(_P_WAIT, cmd[0], cmd); for (p = PPFiles; p != NULL; p = p->next) { if ((file = strrchr(p->str, '\\')) || (file = strrchr(p->str, '/'))) { rename(file + 1, p->str); } } break; case ASM_FILE: if (Option.pfiles == NULL) return 0; for (p = Option.pfiles; p != NULL; p = p->next) { ASMFiles = ListAppend(ASMFiles, FileName(p->str, ".asm")); } Option.afiles = ListCombine(Option.afiles, ASMFiles); cmd = BuildCommand(CCProg, Option.cflags, Option.pfiles, ASMFiles); status = _spawnvp(_P_WAIT, cmd[0], cmd); break; case OBJ_FILE: if (Option.afiles == NULL) return 0; for (p = Option.aflags, Option.aflags = NULL; p != NULL; p = p->next) { Option.aflags = ListCombine(Option.aflags, ParseOption(p->str + 4)); } for (p = Option.afiles; p != NULL; p = p->next) { file = FileName(p->str, ".obj"); OBJFiles = ListAppend(OBJFiles, file); cmd = BuildCommand(ASProg, Option.aflags, ListAppend(NULL, p->str), ListAppend(NULL, file)); status = _spawnvp(_P_WAIT, cmd[0], cmd); } Option.ofiles = ListCombine(Option.ofiles, OBJFiles); break; case LIB_FILE: break; case EXE_FILE: if (Option.ofiles == NULL) return 0; if (Option.out == NULL) { Option.out = Option.ofiles->str; } Option.out = FileName(Option.out, ".exe"); for (p = Option.lflags, Option.lflags = NULL; p != NULL; p = p->next) { Option.lflags = ListCombine(Option.lflags, ParseOption(p->str + 4)); } cmd = BuildCommand(LDProg, Option.lflags, Option.linput, ListAppend(NULL, Option.out)); status = _spawnvp(_P_WAIT, cmd[0], cmd); break; } return status; }
void KernelStart(char *cmd_args[], unsigned int pmem_size, UserContext *uctxt) { virtual_memory_enabled = false; next_synch_resource_id = 1; // Initialize the interrupt vector table and write the base address // to the REG_VECTOR_BASE register TrapTableInit(); // Create the idle proc UserContext model_user_context = *uctxt; idle_proc = NewBlankPCB(model_user_context); // Perform the malloc for the idle proc's kernel stack page table before making page tables. idle_proc->kernel_stack_page_table = (struct pte *) calloc(KERNEL_STACK_MAXSIZE / PAGESIZE, sizeof(struct pte)); // Build the initial page table for region 0 such that page = frame for all valid pages. region_0_page_table = (struct pte *) calloc(VMEM_0_SIZE / PAGESIZE, sizeof(struct pte)); // Create the idle proc's page table for region 1. CreateRegion1PageTable(idle_proc); // Create the PTEs for the kernel text and data with the proper protections. unsigned int i; for (i = 0; i < kernel_brk_page; i++) { region_0_page_table[i].valid = 1; region_0_page_table[i].pfn = i; if (i < kernel_data_start_page) { // Text section. region_0_page_table[i].prot = PROT_READ | PROT_EXEC; } else { // Data section. region_0_page_table[i].prot = PROT_READ | PROT_WRITE; } } // Create the PTEs for the idle proc's kernel stack with page = frame and the proper protections. unsigned int kernel_stack_base_page = ADDR_TO_PAGE(KERNEL_STACK_BASE); for (i = 0; i < NUM_KERNEL_PAGES; i++) { idle_proc->kernel_stack_page_table[i].valid = 1; idle_proc->kernel_stack_page_table[i].pfn = i + kernel_stack_base_page; idle_proc->kernel_stack_page_table[i].prot = PROT_READ | PROT_WRITE; } // Load this new page table UseKernelStackForProc(idle_proc); idle_proc->kernel_context_initialized = true; // Set the TLB registers for the region 0 page table. WriteRegister(REG_PTBR0, (unsigned int) region_0_page_table); WriteRegister(REG_PTLR0, VMEM_0_SIZE / PAGESIZE); // Set the TLB registers for the region 1 page table. WriteRegister(REG_PTBR1, (unsigned int) idle_proc->region_1_page_table); WriteRegister(REG_PTLR1, VMEM_1_SIZE / PAGESIZE); // Enable virtual memory. Wooooo! TracePrintf(TRACE_LEVEL_DETAIL_INFO, "Enabling virtual memory. Wooooo!\n"); virtual_memory_enabled = true; WriteRegister(REG_VM_ENABLE, 1); // Initialize the physical memory management data structures. Then, initialize the // kernel book keeping structs. // Make idle the current proc since it has a region 1 page table that this call can use. current_proc = idle_proc; InitializePhysicalMemoryManagement(pmem_size); InitBookkeepingStructs(); int rc = LoadProgram("idle", NULL, idle_proc); if (rc != SUCCESS) { TracePrintf(TRACE_LEVEL_TERMINAL_PROBLEM, "KernelStart: FAILED TO LOAD IDLE!!\n"); Halt(); } // Load the init program. char *init_program_name = "init"; if (cmd_args[0]) { init_program_name = cmd_args[0]; } // Load the init program, but first make sure we are pointing to its region 1 page table. PCB *init_proc = NewBlankPCBWithPageTables(model_user_context); WriteRegister(REG_PTBR1, (unsigned int) init_proc->region_1_page_table); WriteRegister(REG_TLB_FLUSH, TLB_FLUSH_1); rc = LoadProgram(init_program_name, cmd_args, init_proc); if (rc != SUCCESS) { TracePrintf(TRACE_LEVEL_TERMINAL_PROBLEM, "KernelStart: FAILED TO LOAD INIT!!\n"); Halt(); } // Make idle the current proc. current_proc = idle_proc; WriteRegister(REG_PTBR1, (unsigned int) idle_proc->region_1_page_table); WriteRegister(REG_TLB_FLUSH, TLB_FLUSH_1); // Place the init proc in the ready queue. // On the first clock tick, the init process will be initialized and ran. ListAppend(ready_queue, init_proc, init_proc->pid); // Use the idle proc's user context after returning from KernelStart(). *uctxt = idle_proc->user_context; }
/* No SSL_writev() provided by OpenSSL. Boo. */ int SSLSocket_putdatas(SSL* ssl, int socket, char* buf0, size_t buf0len, int count, char** buffers, size_t* buflens, int* frees) { int rc = 0; int i; char *ptr; iobuf iovec; int sslerror; FUNC_ENTRY; iovec.iov_len = buf0len; for (i = 0; i < count; i++) iovec.iov_len += buflens[i]; ptr = iovec.iov_base = (char *)malloc(iovec.iov_len); memcpy(ptr, buf0, buf0len); ptr += buf0len; for (i = 0; i < count; i++) { memcpy(ptr, buffers[i], buflens[i]); ptr += buflens[i]; } SSL_lock_mutex(&sslCoreMutex); if ((rc = SSL_write(ssl, iovec.iov_base, iovec.iov_len)) == iovec.iov_len) rc = TCPSOCKET_COMPLETE; else { sslerror = SSLSocket_error("SSL_write", ssl, socket, rc); if (sslerror == SSL_ERROR_WANT_WRITE) { int* sockmem = (int*)malloc(sizeof(int)); int free = 1; Log(TRACE_MIN, -1, "Partial write: incomplete write of %d bytes on SSL socket %d", iovec.iov_len, socket); SocketBuffer_pendingWrite(socket, ssl, 1, &iovec, &free, iovec.iov_len, 0); *sockmem = socket; ListAppend(s.write_pending, sockmem, sizeof(int)); FD_SET(socket, &(s.pending_wset)); rc = TCPSOCKET_INTERRUPTED; } else rc = SOCKET_ERROR; } SSL_unlock_mutex(&sslCoreMutex); if (rc != TCPSOCKET_INTERRUPTED) free(iovec.iov_base); else { int i; free(buf0); for (i = 0; i < count; ++i) { if (frees[i]) free(buffers[i]); } } FUNC_EXIT_RC(rc); return rc; }
static int Parse( char *Cmd ) /***************************/ { char opt; char *end; FILE *atfp; char buffer[_MAX_PATH]; char unquoted[_MAX_PATH]; size_t len; char *p; int wcc_option; list *new_item; /* Cmd will always begin with at least one */ /* non-space character if we get this far */ for( ;; ) { Cmd = SkipSpaces( Cmd ); if( *Cmd == '\0' ) break; opt = *Cmd; if( opt == '-' || opt == Switch_Chars[1] ) { Cmd++; } else if( opt != '@' ) { opt = ' '; } end = Cmd; if( *Cmd == '"' ) { end = FindNextWS( end ); } else { end = FindNextWSOrOpt( end, opt, Switch_Chars ); } len = end - Cmd; if( len != 0 ) { if( opt == ' ' ) { /* if filename, add to list */ strncpy( Word, Cmd, len ); Word[len] = '\0'; end = ScanFName( end, len ); UnquoteFName( unquoted, sizeof( unquoted ), Word ); new_item = MemAlloc( sizeof( list ) ); new_item->next = NULL; new_item->item = MemStrDup( unquoted ); if( FileExtension( Word, ".lib" ) ) { ListAppend( &Libs_List, new_item ); } else if( FileExtension( Word, ".res" ) ) { ListAppend( &Res_List, new_item ); } else { ListAppend( &Files_List, new_item ); } } else { /* otherwise, do option */ --len; strncpy( Word, Cmd + 1, len ); Word[len] = '\0'; wcc_option = 1; /* assume it's a wcc option */ switch( tolower( *Cmd ) ) { case 'b': /* possibly -bcl */ if( strnicmp( Word, "cl=", 3 ) == 0 ) { strcat( CC_Opts, " -bt=" ); strcat( CC_Opts, Word+3 ); Flags.link_for_sys = TRUE; MemFree( SystemName ); SystemName = MemStrDup( Word+3 ); wcc_option = 0; } break; case 'f': /* files option */ p = ScanFName( end, len ); switch( tolower( Word[0] ) ) { case 'd': /* name of linker directive file */ if( Word[1] == '=' || Word[1] == '#' ) { end = p; /* remove quotes from target linker control filename */ UnquoteFName( unquoted, sizeof( unquoted ), Word + 2 ); MakeName( unquoted, ".lnk" ); /* add extension */ MemFree( Link_Name ); Link_Name = MemStrDup( unquoted ); } else { MemFree( Link_Name ); Link_Name = MemStrDup( TEMPFILE ); } wcc_option = 0; break; case 'e': /* name of exe file */ if( Word[1] == '=' || Word[1] == '#' ) { end = p; /* remove quotes from target executable filename */ UnquoteFName( unquoted, sizeof( unquoted ), Word + 2 ); strcpy( Exe_Name, unquoted ); } wcc_option = 0; break; case 'i': /* name of forced include file */ end = p; break; case 'm': /* name of map file */ Flags.map_wanted = TRUE; if( Word[1] == '=' || Word[1] == '#' ) { end = p; /* remove quotes from target map filename */ UnquoteFName( unquoted, sizeof( unquoted ), Word + 2 ); MemFree( Map_Name ); Map_Name = MemStrDup( unquoted ); } wcc_option = 0; break; case 'o': /* name of object file */ end = p; /* parse off argument, so we get right filename in linker command file */ p = &Word[1]; if( Word[1] == '=' || Word[1] == '#' ) ++p; /* remove quotes from object name */ UnquoteFName( unquoted, sizeof( unquoted ), p ); MemFree( Obj_Name ); Obj_Name = MemStrDup( unquoted ); break; #if defined( WCLI86 ) || defined( WCL386 ) case 'p': /* floating-point option */ end = p; if( tolower( Word[1] ) == 'c' ) { Flags.math_8087 = 0; } break; #endif default: end = p; break; } break; case 'k': /* stack size option */ if( Word[0] != '\0' ) { MemFree( StackSize ); StackSize = MemStrDup( Word ); } wcc_option = 0; break; case 'l': /* link target option */ switch( (Word[1] << 8) | tolower( Word[0] ) ) { case 'p': Flags.link_for_dos = 0; Flags.link_for_os2 = TRUE; break; case 'r': Flags.link_for_dos = TRUE; Flags.link_for_os2 = 0; break; default: /* 10-jun-91 */ Flags.link_for_sys = TRUE; p = &Word[0]; if( Word[0] == '=' || Word[0] == '#' ) ++p; MemFree( SystemName ); SystemName = MemStrDup( p ); break; } wcc_option = 0; break; case 'x': if( Word[0] == '\0' ) { Flags.two_case = TRUE; wcc_option = 0; } break; case '@': if( Word[0] != '\0' ) { char const * const env = getenv( Word ); if( env != NULL ) { if( handle_environment_variable( env ) ) { return( 1 ); // Recursive call failed } via_environment = TRUE; Cmd = end; continue; } end = ScanFName( end, len ); /* remove quotes from additional linker options file */ UnquoteFName( unquoted, sizeof( unquoted ), Word ); strcpy( Word, unquoted ); MakeName( Word, ".lnk" ); errno = 0; if( (atfp = fopen( Word, "r" )) == NULL ) { PrintMsg( WclMsgs[UNABLE_TO_OPEN_DIRECTIVE_FILE], Word, strerror( errno ) ); return( 1 ); } while( fgets( buffer, sizeof( buffer ), atfp ) != NULL ) { if( strnicmp( buffer, "file ", 5 ) == 0 ) { /* look for names separated by ','s */ p = strchr( buffer, '\n' ); if( p != NULL ) *p = '\0'; AddName( &buffer[5], Fp ); Flags.do_link = TRUE; } else { fputs( buffer, Fp ); } } fclose( atfp ); } wcc_option = 0; break; /* compiler options that affect the linker */ #ifdef WCL386 case '3': case '4': case '5': /* 22-sep-92 */ Conventions = tolower( Word[0] ); break; #endif case 'd': if( DebugFlag == 0 ) { /* not set by -h yet */ if( strcmp( Word, "1" ) == 0 ) { DebugFlag = 1; } else if( strcmp( Word, "1+" ) == 0 ) { /* 02-mar-91 */ DebugFlag = 2; } else if( strcmp( Word, "2" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "2i" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "2s" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "3" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "3i" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "3s" ) == 0 ) { DebugFlag = 2; } } break; case 'h': if( strcmp( Word, "w" ) == 0 ) { DebugFlag = 3; } else if( strcmp( Word, "c" ) == 0 ) { /* 02-mar-91 */ Flags.do_cvpack = 1; DebugFlag = 4; } else if( strcmp( Word, "d" ) == 0 ) { DebugFlag = 5; } break; case 'i': /* include file path */ end = ScanFName( end, len ); break; case 'c': /* compile only */ if( stricmp( Word, "c" ) == 0 ) { Flags.force_c = TRUE; } else if( stricmp( Word, "c++" ) == 0 ) { Flags.force_c_plus = TRUE; } else { Flags.no_link = TRUE; } wcc_option = 0; break; case 'y': if( stricmp( Word, "x" ) == 0 ) { strcat( CC_Opts, " -x" ); wcc_option = 0; } else if( Word[0] == '\0' ) { wcc_option = 0; } break; #if defined( WCLI86 ) || defined( WCL386 ) case 'm': /* memory model */ if( Cmd[1] == 't' || Cmd[1] == 'T' ) { /* tiny model*/ Word[0] = 's'; /* change to small */ Flags.tiny_model = TRUE; } break; #endif case 'p': Flags.no_link = TRUE; break; /* this is a preprocessor option */ case 'q': Flags.be_quiet = TRUE; break; case 'z': /* 12-jan-89 */ switch( tolower( Cmd[1] ) ) { case 's': Flags.no_link = TRUE; break; case 'q': Flags.be_quiet = TRUE; break; #ifdef WCLI86 case 'w': Flags.windows = TRUE; #endif } break; case '"': /* 17-dec-91 */ /* As parameter passing to linker is a special case, we need to pass * whole command instead of first character removed. This allows us * to parse also string literals in AddDirective. */ wcc_option = 0; strncpy( Word, Cmd, ++len ); Word[len] = '\0'; AddDirective( len ); break; } /* don't add linker-specific options */ /* to compiler command line: */ if( wcc_option ) { len = strlen( CC_Opts ); CC_Opts[len++] = ' '; CC_Opts[len++] = opt; CC_Opts[len++] = *Cmd; /* keep original case */ CC_Opts[len] = '\0'; strcat( CC_Opts, Word ); } } Cmd = end; } } return( 0 ); }
EFI_STATUS EfiMain(EFI_HANDLE hImage, EFI_SYSTEM_TABLE *pST) { EFI_LOADED_IMAGE *pImage; EFI_STATUS nStatus; EFI_HANDLE hDriver, *hBlkDevs; UINTN nBlkDevs; EFI_DEVICE_PATH *pBootPart, *pBootDisk = NULL; g_hImage = hImage; InitializeLib(hImage, pST); Print(L"%H\n*** UEFI:NTFS multiboot ***"); if (EFI_ERROR((nStatus = BS->OpenProtocol(hImage, &LoadedImageProtocol, &pImage, hImage, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL)))) { Print(L"%E\nUnable to convert handle to interface: %r\n", nStatus); goto end; } pBootPart = DevicePathFromHandle(pImage->DeviceHandle); pBootDisk = GetParentDevice(pBootPart); CHAR16 *pszDev = DevicePathToStr(pBootDisk); Print(L"%N\nDisk: %s\n", pszDev); FreePool(pszDev); Print(L"%H\n[ INFO ] Disconnecting problematic File System drivers\n"); DisconnectBlockingDrivers(); Print(L"%H\n[ WAIT ] Loading NTFS driver"); EFI_DEVICE_PATH *pDrvPath = FileDevicePath(pImage->DeviceHandle, DriverPath); if (pDrvPath == NULL) { Print(L"%E\r[ FAIL ] Unable to construct path to NTFS driver\n"); goto end; } nStatus = BS->LoadImage(FALSE, hImage, pDrvPath, NULL, 0, &hDriver); FreePool(pDrvPath); if (EFI_ERROR(nStatus)) { Print(L"%E\r[ FAIL ] Unable to load NTFS driver: %r\n", nStatus); goto end; } if (EFI_ERROR((nStatus = BS->StartImage(hDriver, NULL, NULL)))) { Print(L"%E\r[ FAIL ] Unable to start NTFS driver: %r\n", nStatus); goto end; } Print(L"%H\r[ OK ] NTFS driver loaded and started\n"); LINKED_LOADER_PATH_LIST_NODE *list = NULL; EFI_DEVICE_PATH *ldr; if (EFI_ERROR((nStatus = BS->LocateHandleBuffer(ByProtocol, &BlockIoProtocol, NULL, &nBlkDevs, &hBlkDevs)))) { Print(L"%E\r[ FAIL ] Unable to enumerate block devices: %r\n", nStatus); goto end; } for (UINTN i = 0; i < nBlkDevs; i++) { EFI_DEVICE_PATH *pDevice = DevicePathFromHandle(hBlkDevs[i]); pszDev = DevicePathToStr(pDevice); Print(L"%N\r[ INFO ] Probing %d devices... [%d] %s", nBlkDevs, i + 1, pszDev); FreePool(pszDev); if (CompareDevicePaths(pDevice, pBootPart) == 0) continue; if (CompareDevicePaths(pDevice, pBootDisk) == 0) continue; EFI_DEVICE_PATH *pDisk = GetParentDevice(pDevice); _Bool probe = CompareDevicePaths(pDisk, pBootDisk) == 0; FreePool(pDisk); #if !defined(_DEBUG) if (!probe) continue; #endif EFI_BLOCK_IO *blkIo; if (EFI_ERROR((nStatus = BS->OpenProtocol(hBlkDevs[i], &BlockIoProtocol, &blkIo, hImage, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL)))) { Print(L"%E\n[ WARN ] Unable to open block device, skipping: %r\n", nStatus); continue; } //No media or not a partition. if ((blkIo->Media == NULL) || (!blkIo->Media->LogicalPartition)) continue; CHAR8 *buffer = AllocatePool(blkIo->Media->BlockSize); if (buffer == NULL) { Print(L"%E\n[ WARN ] Unable to allocate buffer of size %d\n", blkIo->Media->BlockSize); continue; } nStatus = blkIo->ReadBlocks(blkIo, blkIo->Media->MediaId, 0, blkIo->Media->BlockSize, buffer); _Bool isNTFS = CompareMem(&buffer[3], NTFSMagic, sizeof(NTFSMagic)) == 0; FreePool(buffer); if (EFI_ERROR(nStatus)) { Print(L"%E\n[ WARN ] Unable to read block device, skipping: %r\n", nStatus); continue; } if (!isNTFS) continue; Print(L"%H\n[ WAIT ] Attaching NTFS driver to device"); EFI_FILE_IO_INTERFACE *fs; nStatus = BS->OpenProtocol(hBlkDevs[i], &FileSystemProtocol, NULL, hImage, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL); if (nStatus == EFI_UNSUPPORTED) { nStatus = BS->ConnectController(hBlkDevs[i], NULL, NULL, TRUE); } for (UINTN j = 0; j < NUM_RETRIES; j++) { if ((!EFI_ERROR((nStatus = BS->OpenProtocol(hBlkDevs[i], &FileSystemProtocol, &fs, hImage, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL))))) { break; } Print(L"."); BS->Stall(DELAY * 1000000); } if(EFI_ERROR(nStatus)) { Print(L"%E\r[ WARN ] Unable to attach NTFS driver, skipping: %r\n", nStatus); continue; } Print(L"%H\r[ OK ] NTFS driver attached to current device\n"); Print(L"%H\r[ WAIT ] Locating EFI boot loader"); EFI_FILE *fsRoot; if (EFI_ERROR((nStatus = fs->OpenVolume(fs, &fsRoot)))) { Print(L"%E\r[ WARN ] Unable to open root directory, skipping: %r\n", nStatus); continue; } CHAR16 *loader = StrDuplicate(LoaderPath); if (EFI_ERROR((nStatus = SetPathCase(fsRoot, loader)))) { FreePool(loader); Print(L"%E\r[ WARN ] Unable to locate EFI boot loader on this device: %r\n", nStatus); continue; } Print(L"%H\r[ OK ] EFI boot loader located at %s\n", loader); ldr = FileDevicePath(hBlkDevs[i], loader); ListAppend(&list, ldr); FreePool(loader); } UINTN nListEntries = 0, nBootEntry = 0, nPage = 0, nTotalPage = 0; EFI_INPUT_KEY key; _Bool interactive = FALSE; ListTraverse(&list, CountEntries, 0, 0, &nListEntries); switch (nListEntries) { case 0: Print(L"%E\n[ FAIL ] No bootable partition\n", nStatus); nStatus = EFI_NOT_FOUND; goto end; case 1: goto boot; default: nTotalPage = (nListEntries - 1) / PAGE_SIZE + 1; while (1) { ST->ConOut->ClearScreen(ST->ConOut); Print(L"%H*** UEFI:NTFS Multiboot ***\n"); pszDev = DevicePathToStr(pBootDisk); Print(L"%NDisk: %s\n\n%H", pszDev); FreePool(pszDev); ListTraverse(&list, DisplayEntries, nPage * PAGE_SIZE, PAGE_SIZE, NULL); Print(L"%N\nPage %hd / %hd, %hd entries\n", nPage + 1, nTotalPage, nListEntries); Print(L"%H\n[F1 - F8] [1 - 8] %N Boot corresponding entry"); Print(L"%H\n[PgUp] [<] [-] %N Previous page"); Print(L"%H\n[PgDn] [>] [+] %N Next page"); if (!interactive) { INTN nCountDown = AUTOBOOT_TIME; Print(L"%N\n\n"); while (nCountDown >= 0) { Print(L"\rWill automatically boot the first entry in %d seconds...", nCountDown); if (WaitForSingleEvent(ST->ConIn->WaitForKey, 1000 * 1000 * 10) != EFI_TIMEOUT) { interactive = TRUE; break; } nCountDown--; } if (!interactive) { goto boot; } } else { WaitForSingleEvent(ST->ConIn->WaitForKey, 0); } ST->ConIn->ReadKeyStroke(ST->ConIn, &key); switch (key.UnicodeChar) { case L'1':case L'2':case L'3':case L'4':case L'5':case L'6':case L'7':case L'8': nBootEntry = nPage * PAGE_SIZE + (key.UnicodeChar - L'1'); goto boot; case L'+':case L'=':case L'>':case L'.': if ((nPage + 1) != nTotalPage) { nPage++; } break; case L'-':case L'_': case L'<': case L',': if (nPage != 0) { nPage--; } break; default: switch (key.ScanCode) { case 0x09: if (nPage != 0) { nPage--; } break; case 0x0a: if ((nPage + 1) != nTotalPage) { nPage++; } break; case 0x0b:case 0x0c:case 0x0d:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12: nBootEntry = nPage * PAGE_SIZE + (key.ScanCode - 0x0b); goto boot; } } } } boot: ldr = NULL; Print(L"%H"); ST->ConOut->ClearScreen(ST->ConOut); ListTraverse(&list, ReadEntry, nBootEntry, 1, &ldr); ListTraverse(&list, DisplayEntries, nBootEntry, 1, NULL); if (ldr == NULL) { Print(L"%E\n[ FAIL ] No such boot entry\n", nStatus); nStatus = EFI_NOT_FOUND; goto end; } ldr = DuplicateDevicePath(ldr); ListTraverse(&list, DestroyEntries, 0, 0, NULL); ListDestroy(&list); EFI_HANDLE hChain; nStatus = BS->LoadImage(FALSE, hImage, ldr, NULL, 0, &hChain); FreePool(ldr); if (EFI_ERROR(nStatus)) { Print(L"%E\n[ FAIL ] Unable to load boot loader: %r\n", nStatus); goto end; } Print(L"%N"); if (EFI_ERROR((nStatus = BS->StartImage(hChain, NULL, NULL)))) { Print(L"%E\n[ FAIL ] Unable to start boot loader: %r\n", nStatus); goto end; } end: if (pBootDisk) FreePool(pBootDisk); if (EFI_ERROR(nStatus)) { Print(L"Press any key to exit\n"); WaitForSingleEvent(ST->ConIn->WaitForKey, 0); ST->ConIn->ReadKeyStroke(ST->ConIn, &key); } return nStatus; }
static int ParseArgs( int argc, char **argv ) /*********************************************/ { char *p; int wcc_option; int c; int i; list *new_item; initialize_Flags(); DebugFlag = 1; StackSize = NULL; Conventions[0] = 'r'; Conventions[1] = '\0'; preprocess_only = 0; cpp_want_lines = 1; /* NB: wcc and wcl default to 0 here */ cpp_keep_comments = 0; cpp_encrypt_names = 0; cpp_linewrap = NULL; O_Name = NULL; AltOptChar = '-'; /* Suppress '/' as option herald */ while( (c = GetOpt( &argc, argv, #if 0 "b:Cc::D:Ef:g::" "HI:i::k:L:l:M::m:" "O::o:P::QSs::U:vW::wx:yz::", #else "b:CcD:Ef:g::" "HI:i::k:L:l:M::m:" "O::o:P::QSs::U:vW::wx::yz::", #endif EnglishHelp )) != -1 ) { char *Word = ""; int found_mapping = FALSE; for( i = 0; i < sizeof( mappings ) / sizeof( mappings[0] ); i++ ) { option_mapping *m = mappings + i; char *tail = strchr( m->LongName, ':' ); if( c != m->LongName[0] ) continue; if( OptArg == NULL ) { if( m->LongName[1] == '\0' ) { strcat( CC_Opts, " -" ); strcat( CC_Opts, m->WatcomName ); found_mapping = TRUE; break; } /* non-existant argument can't match other cases */ continue; } if( tail != NULL ) { if( !strncmp( OptArg, m->LongName + 1, tail - m->LongName - 1 ) ) { strcat( CC_Opts, " -" ); strcat( CC_Opts, m->WatcomName ); strcat( CC_Opts, OptArg + ( tail - m->LongName - 1) ); found_mapping = TRUE; break; } } else if( !strcmp( OptArg, m->LongName + 1 ) ) { strcat( CC_Opts, " -" ); strcat( CC_Opts, m->WatcomName ); found_mapping = TRUE; break; } } if( found_mapping ) continue; if( OptArg != NULL ) { Word = MemAlloc( strlen( OptArg ) + 6 ); strcpy( Word, OptArg ); } wcc_option = 1; switch( c ) { case 'f': if( !strcmp( Word, "syntax-only" ) ) { c = 'z'; strcpy( Word, "s" ); Flags.no_link = 1; break; } if( !strncmp( Word, "cpp-wrap=", 9 ) ) { MemFree( cpp_linewrap ); Word[7] = 'w'; cpp_linewrap = MemStrDup( Word + 7 ); wcc_option = 0; break; } if( !strcmp( Word, "mangle-cpp" ) ) { cpp_encrypt_names = 1; wcc_option = 0; break; } switch( Word[0] ) { case 'd': /* name of linker directive file */ if( Word[1] == '=' || Word[1] == '#' ) { MakeName( Word, ".lnk" ); /* add extension */ MemFree( Link_Name ); Link_Name = strfdup( Word + 2 ); } else { MemFree( Link_Name ); Link_Name = MemStrDup( TEMPFILE ); } wcc_option = 0; break; case 'm': /* name of map file */ Flags.map_wanted = TRUE; if( Word[1] == '=' || Word[1] == '#' ) { MemFree( Map_Name ); Map_Name = strfdup( Word + 2 ); } wcc_option = 0; break; case 'o': /* name of object file */ /* parse off argument, so we get right filename in linker command file */ p = &Word[1]; if( Word[1] == '=' || Word[1] == '#' ) { ++p; } MemFree( Obj_Name ); Obj_Name = strfdup( p ); /* 08-mar-90 */ break; case 'r': /* name of error report file */ Flags.want_errfile = TRUE; break; } /* avoid passing on unknown options */ wcc_option = 0; break; case 'k': /* stack size option */ if( Word[0] != '\0' ) { MemFree( StackSize ); StackSize = MemStrDup( Word ); } wcc_option = 0; break; /* compiler options that affect the linker */ case 'c': /* compile only */ Flags.no_link = TRUE; wcc_option = 0; break; case 'x': /* change source language */ if( strcmp( Word, "c" ) == 0 ) { Flags.force_c = TRUE; } else if( strcmp( Word, "c++" ) == 0 ) { Flags.force_c_plus = TRUE; } else { Flags.no_link = TRUE; } wcc_option = 0; break; case 'm': if( ( !strncmp( "cmodel=", Word, 7 ) ) && ( Word[8] == '\0' ) ) { if( Word[7] == 't' ) { /* tiny model */ Word[0] = 's'; /* change to small */ Flags.tiny_model = TRUE; } else { Word[0] = Word[7]; } Word[1] = '\0'; break; } if( !strncmp( "regparm=", Word, 8 ) ) { if( !strcmp( Word + 8, "0" ) ) { Conventions[0] = 's'; } else { Conventions[0] = 'r'; } wcc_option = 0; break; } if( !strncmp( "tune=i", Word, 6 ) ) { switch( Word[6] ) { case '0': case '1': case '2': CPU_Class = Word[6]; Conventions[0] = '\0'; break; case '3': case '4': case '5': case '6': CPU_Class = Word[6]; break; default: /* Unknown CPU type --- disable generation of this * option */ CPU_Class = '\0'; } wcc_option = 0; break; } wcc_option = 0; /* dont' pass on unknown options */ break; case 'z': /* 12-jan-89 */ switch( tolower( Word[0] ) ) { case 's': Flags.no_link = TRUE; break; case 'q': Flags.be_quiet = TRUE; break; case 'w': Flags.windows = TRUE; } break; case 'E': preprocess_only = 1; wcc_option = 0; break; case 'P': cpp_want_lines = 0; wcc_option = 0; break; case 'C': cpp_keep_comments = 1; wcc_option = 0; break; case 'o': MemFree( O_Name ); O_Name = strfdup( OptArg ); wcc_option = 0; break; case 'g': if( OptArg == NULL ) { Word = "2"; } else if( !isdigit( OptArg[0] ) ) { c = 'h'; if( strcmp( Word, "w" ) == 0 ) { DebugFlag = 3; } else if( strcmp( Word, "c" ) == 0 ) { /* 02-mar-91 */ Flags.do_cvpack = 1; DebugFlag = 4; } else if( strcmp( Word, "d" ) == 0 ) { DebugFlag = 5; } break; } c = 'd'; parse_d: if( DebugFlag == 0 ) { /* not set by -h yet */ if( strcmp( Word, "1" ) == 0 ) { DebugFlag = 1; } else if( strcmp( Word, "1+" ) == 0 ) { /* 02-mar-91 */ DebugFlag = 2; } else if( strcmp( Word, "2" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "2i" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "2s" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "3" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "3i" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "3s" ) == 0 ) { DebugFlag = 2; } } break; case 'S': Flags.do_disas = TRUE; Flags.no_link = TRUE; if( DebugFlag == 0 ) { c = 'd'; Word = "1"; goto parse_d; } wcc_option = 0; break; case 's': if( OptArg != NULL ) { /* leave -shared to mapping table */ wcc_option = 0; break; } Flags.strip_all = 1; DebugFlag = 0; wcc_option = 0; break; case 'v': Flags.be_quiet = 0; wcc_option = 0; break; case 'W': if( OptArg != NULL && strncmp( OptArg, "l,", 2 ) == 0 ) { AddDirective( OptArg + 2 ); wcc_option = 0; } /* other cases handled by table */ break; case 'I': xlate_fname( Word ); break; case 'b': Flags.link_for_sys = TRUE; MemFree( SystemName ); SystemName = MemStrDup( Word ); /* if Word found in specs.owc, add options from there: */ if( ConsultSpecsFile( Word ) ) { /* all set */ wcc_option = 0; } else { /* not found --- default to bt=<system> */ strcpy( Word, "t=" ); strcat( Word, SystemName ); } break; case 'l': new_item = MemAlloc( sizeof( list ) ); new_item->next = NULL; p = MemAlloc( strlen( OptArg ) + 2 + 1 ); strcpy( p, OptArg ); strcat( p, ".a" ); new_item->item = strfdup( p ); MemFree( p ); ListAppend( &Libs_List, new_item ); wcc_option = 0; break; case 'L': xlate_fname( Word ); fputs( "libpath ", Fp ); Fputnl( Word, Fp ); wcc_option = 0; break; case 'i': /* -include <file> --> -fi=<file> */ if( OptArg == NULL ) { wcc_option = 0; break; } if( !strcmp( OptArg, "nclude" ) ) { c = 'f'; Word = MemReAlloc( Word, strlen( argv[OptInd] ) + 6 ); if( OptInd >= argc - 1 ) { MemFree( cpp_linewrap ); PrintMsg( "Argument of -include missing\n", OptArg ); return( 1 ); } strcpy( Word, "i=" ); strfcat( Word, argv[OptInd] ); argv[OptInd++][0] = '\0'; break; } /* avoid passing un unknown options */ wcc_option = 0; break; case 'M': /* autodepend information for Unix makes */ if( OptArg == NULL ) { wcc_option = 0; break; } c = 'a'; if( !strcmp( OptArg, "D" ) || !strcmp( OptArg, "MD" ) ) { /* NB: only -MMD really matches OW's behaviour, but * for now, let's accept -MD to mean the same */ /* translate to -adt=.o */ strcpy( Word, "dt=.o" ); } else if( !strcmp( OptArg, "F" ) ) { Word = MemReAlloc( Word, strlen( argv[OptInd] ) + 6 ); if( OptInd >= argc - 1 ) { MemFree( cpp_linewrap ); PrintMsg( "Argument of -MF missing\n", OptArg ); return( 1 ); } strcpy( Word, "d=" ); strfcat( Word, argv[OptInd] ); argv[OptInd++][0] = '\0'; } else if( !strcmp( OptArg, "T") ) { Word = MemReAlloc( Word, strlen( argv[OptInd] ) + 6 ); if( OptInd >= argc - 1 ) { MemFree( cpp_linewrap ); PrintMsg( "Argument of -M%s missing\n", OptArg ); return( 1 ); } strcpy( Word, "dt=" ); strcat( Word, argv[OptInd] ); argv[OptInd++][0] = '\0'; } else { /* avoid passing on incompatible options */ wcc_option = 0; } break; } /* don't add linker-specific options */ /* to compiler command line: */ if( wcc_option ) { addccopt( c, Word ); } if( OptArg != NULL ) { MemFree( Word ); Word = NULL; } } if( preprocess_only ) { Flags.no_link = TRUE; if( O_Name == NULL ) { MemFree( Obj_Name ); /* preprocess to stdout by default */ Obj_Name = NULL; } strcat( CC_Opts, " -p" ); if( cpp_encrypt_names ) strcat( CC_Opts, "e" ); if( cpp_want_lines ) strcat( CC_Opts, "l" ); if( cpp_keep_comments ) strcat( CC_Opts, "c" ); if( cpp_linewrap != NULL ) { strcat( CC_Opts, cpp_linewrap ); } } if( CPU_Class ) addccopt( CPU_Class, Conventions ); if( Flags.be_quiet ) addccopt( 'z', "q" ); if( O_Name != NULL ) { if( Flags.no_link && !Flags.do_disas ) { MemFree( Obj_Name ); Obj_Name = O_Name; } else { strcpy( Exe_Name, O_Name ); Flags.keep_exename = 1; MemFree( O_Name ); } O_Name = NULL; } if( Obj_Name != NULL ) { strcat( CC_Opts, " -fo=" ); strcat( CC_Opts, Obj_Name ); } if( !Flags.want_errfile ) { strcat( CC_Opts, " -fr" ); } for( i = 1; i < argc ; i++ ) { Word = argv[i]; if( Word == NULL || Word[0] == '\0' ) /* HBB 20060217: argument was used up */ continue; new_item = MemAlloc( sizeof( list ) ); new_item->next = NULL; new_item->item = strfdup( Word ); if( FileExtension( Word, ".lib" ) || FileExtension( Word, ".a" ) ) { ListAppend( &Libs_List, new_item ); } else { ListAppend( &Files_List, new_item ); } } MemFree( cpp_linewrap ); return( 0 ); }
/** * Process an incoming publish packet for a socket * @param pack pointer to the publish packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handlePublishes(void* pack, int sock) { Publish* publish = (Publish*)pack; Clients* client = NULL; char* clientid = NULL; int rc = TCPSOCKET_COMPLETE; #if !defined(SINGLE_LISTENER) Listener* listener = Socket_getParentListener(sock); #endif FUNC_ENTRY; if (sock == 0) clientid = INTERNAL_CLIENTID; /* this is an internal client */ else { client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content); clientid = client->clientID; Log(LOG_PROTOCOL, 11, NULL, sock, clientid, publish->msgId, publish->header.bits.qos, publish->header.bits.retain, min(20, publish->payloadlen), publish->payload); if (Protocol_isClientQuiescing(client)) goto exit; /* don't accept new work */ #if !defined(SINGLE_LISTENER) if (listener && listener->mount_point) { char* temp = malloc(strlen(publish->topic) + strlen(listener->mount_point) + 1); strcpy(temp, listener->mount_point); strcat(temp, publish->topic); free(publish->topic); publish->topic = temp; } #endif } #if !defined(NO_BRIDGE) if (client && client->outbound) Bridge_handleInbound(client, publish); #endif if (publish->header.bits.qos == 0) { if (strlen(publish->topic) < 5 || strncmp(publish->topic, sysprefix, strlen(sysprefix)) != 0) { ++(bstate->msgs_received); bstate->bytes_received += publish->payloadlen; } Protocol_processPublication(publish, clientid); } else if (publish->header.bits.qos == 1) { /* send puback before processing the publications because a lot of return publications could fill up the socket buffer */ rc = MQTTPacket_send_puback(publish->msgId, sock, clientid); /* if we get a socket error from sending the puback, should we ignore the publication? */ Protocol_processPublication(publish, clientid); ++(bstate->msgs_received); bstate->bytes_received += publish->payloadlen; } else if (publish->header.bits.qos == 2) { /* store publication in inbound list */ int len; ListElement* listElem = NULL; Messages* m = NULL; Publications* p = NULL; /*if list is full, disconnect the client with warning message */ if (client->inboundMsgs->count >= (bstate->max_inflight_messages*2)) { Log(LOG_WARNING, 69, NULL, clientid); rc = SOCKET_ERROR; /* will cause the client to be disconnected */ goto exit; } p = MQTTProtocol_storePublication(publish, &len); if ((listElem = ListFindItem(client->inboundMsgs, &publish->msgId, messageIDCompare)) != NULL) { m = (Messages*)(listElem->content); MQTTProtocol_removePublication(m->publish); /* remove old publication data - could be different */ } else m = malloc(sizeof(Messages)); m->publish = p; m->msgid = publish->msgId; m->qos = publish->header.bits.qos; m->priority = publish->priority; m->retain = publish->header.bits.retain; m->nextMessageType = PUBREL; if (listElem == NULL) ListAppend(client->inboundMsgs, m, sizeof(Messages) + len); rc = MQTTPacket_send_pubrec(publish->msgId, sock, clientid); } exit: if (sock < -1 || sock > 0) MQTTPacket_freePublish(publish); FUNC_EXIT_RC(rc); return rc; }
int Protocol_handlePublishes(Publish* publish, int sock, Clients* client, char* clientid) #endif { int rc = TCPSOCKET_COMPLETE; #if !defined(SINGLE_LISTENER) Listener* listener = NULL; #endif FUNC_ENTRY; if (Protocol_isClientQuiescing(client)) goto exit; /* don't accept new work */ #if !defined(SINGLE_LISTENER) listener = Socket_getParentListener(sock); if (listener && listener->mount_point) { char* temp = malloc(strlen(publish->topic) + strlen(listener->mount_point) + 1); strcpy(temp, listener->mount_point); strcat(temp, publish->topic); free(publish->topic); publish->topic = temp; } #endif #if !defined(NO_BRIDGE) if (client && client->outbound) Bridge_handleInbound(client, publish); #endif if (publish->header.bits.qos == 0) { if (strlen(publish->topic) < 5 || strncmp(publish->topic, sysprefix, strlen(sysprefix)) != 0) { ++(bstate->msgs_received); bstate->bytes_received += publish->payloadlen; } Protocol_processPublication(publish, clientid); } else if (publish->header.bits.qos == 1) { /* send puback before processing the publications because a lot of return publications could fill up the socket buffer */ #if defined(MQTTS) if (client->protocol == PROTOCOL_MQTTS) rc = MQTTSPacket_send_puback(client, topicId, publish->msgId, MQTTS_RC_ACCEPTED); else #endif rc = MQTTPacket_send_puback(publish->msgId, sock, clientid); /* if we get a socket error from sending the puback, should we ignore the publication? */ Protocol_processPublication(publish, clientid); ++(bstate->msgs_received); bstate->bytes_received += publish->payloadlen; } else if (publish->header.bits.qos == 2 && client->inboundMsgs->count < bstate->max_inflight_messages) { /* store publication in inbound list - if list is full, ignore and rely on client retry */ int len; ListElement* listElem = NULL; Messages* m = NULL; Publications* p = MQTTProtocol_storePublication(publish, &len); if ((listElem = ListFindItem(client->inboundMsgs, &publish->msgId, messageIDCompare)) != NULL) { m = (Messages*)(listElem->content); MQTTProtocol_removePublication(m->publish); /* remove old publication data - could be different */ } else m = malloc(sizeof(Messages)); m->publish = p; m->msgid = publish->msgId; m->qos = publish->header.bits.qos; m->retain = publish->header.bits.retain; m->nextMessageType = PUBREL; if (listElem == NULL) ListAppend(client->inboundMsgs, m, sizeof(Messages) + len); #if defined(MQTTS) if (client->protocol == PROTOCOL_MQTTS) rc = MQTTSPacket_send_pubrec(client, publish->msgId); else #endif rc = MQTTPacket_send_pubrec(publish->msgId, sock, clientid); } else if (publish->header.bits.qos == 3) /* only applies to MQTT-S */ { publish->header.bits.qos = 0; Protocol_processPublication(publish, clientid); } exit: if (sock > 0) MQTTPacket_freePublish(publish); FUNC_EXIT_RC(rc); return rc; }
EXPR *FindBasic( EXPR *def ) { unsigned int i ; EXPR *expr, *E1, *E2 ; if( IsReal(def) ) { expr = new UNIT ; U(expr)->Ehead = String( "Ordinate" ) ; ListAppend( expr, def->Copy() ) ; return expr ; } if( IsLabel( def ) ) { for( i = 0 ; i < U(UnitList)->used ; i++ ) { if( U(UN(i))->Ehead == def ) { expr = UN(i)->Copy() ; delete U(expr)->Eeval ; U(expr)->Eeval = NULL_EXPR ; return expr ; } } IOerror( IO_ERR, "FindBasic", "%s is an undefined unit", LabelValue(def) ) ; return garbageunit() ; } if( !IsOper(def) ) { IOerror( IO_FATAL, "FindBasic", "unexpected in units definition" ) ; return garbageunit() ; } if( D(def)->oper == OPER_MINUS ) { expr = FindBasic( D(def)->Eleft ) ; if( U(expr)->used > 1 ) { IOerror( IO_ERR, "FindBasic", "illegal negation of unit" ) ; return garbageunit() ; } E1 = OP3( "u-", U(expr)->list[0], NULL_EXPR ) ; delete U(expr)->list[0] ; U(expr)->list[0] = E1 ; return expr ; } E1 = FindBasic( D(def)->Eleft ) ; E2 = FindBasic( D(def)->Eright ) ; switch( D(def)->oper ) { case OPER_MULTIPLY: expr = UnitOP3( "*", "+", E1, E2 ) ; break ; case OPER_DIVIDE: expr = UnitOP3( "/", "-", E1, E2 ) ; break ; case OPER_POW: expr = UnitOP3( "^", "*", E1, E2 ) ; break ; default: IOerror( IO_ERR, "FindBasic", "unexpected operator in unit" ) ; expr = garbageunit() ; break ; } delete E1 ; delete E2 ; return expr ; }
uint8_t fhssDistributedBlacklistMABFirstBestArmChan(Node_t *parent, Node_t *child, uint64_t asn) { uint8_t freq = 0; /* Every epsilon_ts_incr_n time slots we divide increment epsilon_n */ if ((epsilon_ts_incr_n != 0) && ((asn + 1) % epsilon_ts_incr_n) == 0) { if (++epsilon_n == epsilon_max_n) { epsilon_n = epsilon_init_n; PRINTF("Reseting Epsilon to %ld at %lld\n", (long)epsilon_init_n, (long long)asn); } } if ((rand() % epsilon_n) == 0) { /* We will explore all channels randomly */ return (fhssDistributedBlacklistMABExplore(parent, asn)); } else { /* Lets order all channel sorting by average_reward */ List ordered_channel; memset(&ordered_channel, 0, sizeof(List)); ListInit(&ordered_channel); for (uint8_t i = 0; i < NUM_CHANNELS; i++) { ListElem *elem; for (elem = ListFirst(&ordered_channel); elem != NULL; elem = ListNext(&ordered_channel, elem)) { uint8_t channel = (uint8_t)elem->obj; if (parent->avg_reward[child->id][i] > parent->avg_reward[child->id][channel]) { ListInsertBefore(&ordered_channel, (void *)i, elem); break; } } if (elem == NULL) { ListAppend(&ordered_channel, (void *)i); } } /* Create a blacklist with the first best MAB_FIRST_BEST_ARMS channels */ uint16_t blacklist = 0; uint8_t n_channels = 1; for (ListElem *elem = ListFirst(&ordered_channel); elem != NULL; elem = ListNext(&ordered_channel, elem)) { uint8_t channel = (uint8_t)elem->obj; blacklist |= (1 << channel); /* Check if we already got the MAB_FIRST_BEST_ARMS first best channels */ if (++n_channels > mab_first_best_arms) { break; } } for (ListElem *elem = ListFirst(&parent->channels); elem != NULL; elem = ListNext(&parent->channels, elem)) { uint8_t freq_off = (uint8_t)elem->obj; freq = fhssOpenwsnChan(freq_off, asn); if (blacklist & (1 << freq)) { return (freq); } } return (freq); } return 0; }
/** * Restores the persisted records to the outbound and inbound message queues of the * client. * @param client the client as ::Clients. * @return 0 if success, #MQTTCLIENT_PERSISTENCE_ERROR otherwise. */ int MQTTPersistence_restore(Clients *c) { int rc = 0; char **msgkeys = NULL, *buffer = NULL; int nkeys, buflen; int i = 0; int msgs_sent = 0; int msgs_rcvd = 0; FUNC_ENTRY; if (c->persistence && (rc = c->persistence->pkeys(c->phandle, &msgkeys, &nkeys)) == 0) { while (rc == 0 && i < nkeys) { if (strncmp(msgkeys[i], PERSISTENCE_COMMAND_KEY, strlen(PERSISTENCE_COMMAND_KEY)) == 0) ; else if (strncmp(msgkeys[i], PERSISTENCE_QUEUE_KEY, strlen(PERSISTENCE_QUEUE_KEY)) == 0) ; else if ((rc = c->persistence->pget(c->phandle, msgkeys[i], &buffer, &buflen)) == 0) { MQTTPacket* pack = MQTTPersistence_restorePacket(buffer, buflen); if ( pack != NULL ) { if ( strstr(msgkeys[i],PERSISTENCE_PUBLISH_RECEIVED) != NULL ) { Publish* publish = (Publish*)pack; Messages* msg = NULL; msg = MQTTProtocol_createMessage(publish, &msg, publish->header.bits.qos, publish->header.bits.retain); msg->nextMessageType = PUBREL; /* order does not matter for persisted received messages */ ListAppend(c->inboundMsgs, msg, msg->len); publish->topic = NULL; MQTTPacket_freePublish(publish); msgs_rcvd++; } else if ( strstr(msgkeys[i],PERSISTENCE_PUBLISH_SENT) != NULL ) { Publish* publish = (Publish*)pack; Messages* msg = NULL; char *key = malloc(MESSAGE_FILENAME_LENGTH + 1); sprintf(key, "%s%d", PERSISTENCE_PUBREL, publish->msgId); msg = MQTTProtocol_createMessage(publish, &msg, publish->header.bits.qos, publish->header.bits.retain); if ( c->persistence->pcontainskey(c->phandle, key) == 0 ) /* PUBLISH Qo2 and PUBREL sent */ msg->nextMessageType = PUBCOMP; /* else: PUBLISH QoS1, or PUBLISH QoS2 and PUBREL not sent */ /* retry at the first opportunity */ msg->lastTouch = 0; MQTTPersistence_insertInOrder(c->outboundMsgs, msg, msg->len); publish->topic = NULL; MQTTPacket_freePublish(publish); free(key); msgs_sent++; } else if ( strstr(msgkeys[i],PERSISTENCE_PUBREL) != NULL ) { /* orphaned PUBRELs ? */ Pubrel* pubrel = (Pubrel*)pack; char *key = malloc(MESSAGE_FILENAME_LENGTH + 1); sprintf(key, "%s%d", PERSISTENCE_PUBLISH_SENT, pubrel->msgId); if ( c->persistence->pcontainskey(c->phandle, key) != 0 ) rc = c->persistence->premove(c->phandle, msgkeys[i]); free(pubrel); free(key); } } else /* pack == NULL -> bad persisted record */ rc = c->persistence->premove(c->phandle, msgkeys[i]); } if (buffer) { free(buffer); buffer = NULL; } if (msgkeys[i]) free(msgkeys[i]); i++; } if (msgkeys) free(msgkeys); } Log(TRACE_MINIMUM, -1, "%d sent messages and %d received messages restored for client %s\n", msgs_sent, msgs_rcvd, c->clientID); MQTTPersistence_wrapMsgID(c); FUNC_EXIT_RC(rc); return rc; }