📄 main_broker.c
字号:
netError(comSock,PERM_DENIED_ERROR); break; } cp=(char *)strtok(packet+2, ":\n\r"); arg = (char *)strdup(cp); cp=(char *)strtok(NULL, "\n\r"); arg2 = (char *)strdup(cp); processCopyDB(server, comSock,arg, arg2); if(arg) free(arg); if(arg2) free(arg2); break; case MOVE_DB: if (!aclCheckLocal(conArray + count)) { netError(comSock,PERM_DENIED_ERROR); break; } cp=(char *)strtok(packet+2, ":\n\r"); arg = (char *)strdup(cp); cp=(char *)strtok(NULL, "\n\r"); arg2 = (char *)strdup(cp); processMoveDB(server, comSock,arg, arg2); if(arg) free(arg); if(arg2) free(arg2); /* Send broker update request */ _zeroMessageStruct(&message); message.command = CMD_FLUSH_CACHE; message.client = 0; strcpy(message.db, arg); brokerChildSendMessage(&message); break; case DROP_DB: if (!aclCheckLocal(conArray + count)) { netError(comSock,PERM_DENIED_ERROR); break; } cp=(char *)strtok(packet+2, "\n\r"); arg = (char *)strdup(cp); processDropDB(server, comSock,arg); /* Send broker update request */ _zeroMessageStruct(&message); message.command = CMD_FLUSH_CACHE; message.client = 0; strcpy(message.db, arg); brokerChildSendMessage(&message); if(arg) free(arg); break; case RELOAD_ACL: if (!aclCheckLocal(conArray + count)) { netError(comSock,PERM_DENIED_ERROR); break; } aclReloadFile(comSock); netEndOfList(comSock); break; case SHUTDOWN: if (!aclCheckLocal(conArray + count)) { netError(comSock,PERM_DENIED_ERROR); break; } netEndOfList(comSock); puntServer(-1); exit(0); break; case SERVER_STATS: if (!aclCheckLocal(conArray + count)) { netError(comSock,PERM_DENIED_ERROR); break; } sendServerStats(comSock); netEndOfList(comSock); break; default: netError(comSock, UNKNOWN_COM_ERROR); break; } /* ** Fall out of the loop so that we process ** requests in sequence. Otherwise we may ** have given away the select lock when we ** actually need it (like INIT_DB) */ break; } if(haveLock) { lockReleaseIpcLock(server); } if (clientsProcessed == 0) { /* ** Something strange is going on. We fell out ** of select but didn't do anything. The client ** fdset and the connection table must not match */ printf("Bad client FD_SET in %d!\n", (int)getpid()); abort(); } }}void debugTrap(){ /* We use this as a debugger breakpoint */}int main(argc,argv) int argc; char *argv[];{ msqld server; fd_set readFDs, children; int sock, newSock, maxSock, maxChildSock, opt, error, errFlag = 0, lockFD, c; char *uname, *ipAddr, path[MSQL_PATH_LEN], pidBuf[10]; int pidFD; extern char *optarg;#ifdef HAVE_SETRLIMIT struct rlimit limit;#endif struct passwd *pwd; struct stat sbuf; struct sockaddr_in remote;#ifdef DEBUG_BSD_MALLOC extern char *malloc_options; malloc_options = "AJ";#endif serverStartTime = time(NULL); printf("\n\nMini SQL Version %s\n",SERVER_VERSION); printf("Copyright (c) 1993-94 David J. Hughes\n"); printf("Copyright (c) 1995-2004 Hughes Technologies Pty Ltd.\n"); printf("All rights reserved.\n\n"); /* Try to set the locale but don't bail if it fails (freeBSD) */ setlocale(LC_ALL, ""); /* ** Handle the command line args */ *confFile = 0; while((c=getopt(argc,argv,"f:"))!= -1) { switch(c) { case 'f': if (*confFile) errFlag++; else strcpy(confFile,optarg); break; case '?': errFlag++; break; } } if (errFlag) { usage(); exit(1); } if (*confFile == 0) { snprintf(confFile,sizeof(confFile),"%s/msql.conf", INST_DIR); } printf("\tLoading configuration from '%s'.\n",confFile); configLoadFile(confFile); bzero(&server, sizeof(server)); globalServer = &server; server.config.instDir=strdup(configGetCharEntry("general","inst_dir")); server.config.dbDir = strdup(configGetCharEntry("general", "db_dir")); server.config.readOnly = configGetIntEntry("system", "read_only"); server.config.msyncTimer = configGetIntEntry("system", "msync_timer"); server.config.sortMaxMem = configGetIntEntry("system","sort_max_mem"); server.config.tableCache = configGetIntEntry("system","table_cache"); server.config.cacheDescriptors = server.config.tableCache * (NUM_INDEX + 2); server.config.needFileLock = 1; server.config.hasBroker = 1; /* ** Check out the file descriptor limit ** ** Some boxes have broken getrlimit() implementations (or ** missing RLIMIT_NOFILE) so we try to use sysconf first ** ** Watch out for broken BSDI here. It looks like BSDI returns ** the kernel MAX_FILES not the per process MAX_FILE in ** getrlimit() which kinda sucks if you want to use select()! */# ifdef HAVE_RLIMIT_NOFILE getrlimit(RLIMIT_NOFILE,&limit); limit.rlim_cur = (limit.rlim_max > 256)? 256 : limit.rlim_max; setrlimit(RLIMIT_NOFILE,&limit); getrlimit(RLIMIT_NOFILE,&limit); maxCons = limit.rlim_cur-globalServer->config.cacheDescriptors; printf("\tServer process reconfigured to accept %d ",maxCons); printf("connections.\n");# else# ifdef HAVE_SYSCONF maxCons = sysconf(_SC_OPEN_MAX)- globalServer->config.cacheDescriptors; printf("\tServer process reconfigured to accept %d ",maxCons); printf("connections.\n");# else maxCons = 64 - globalServer->config.cacheDescriptors; printf("\tDynamic server config failed!\n"); printf("\tServer can accept %d connections.\n", maxCons);# endif# endif if (maxCons > 254) maxCons = 254; /* ** We have to do this now. If msql is configured to run as nobody ** then nobody would have to have write perms for the INST_DIR ** This way we can start as root and then run as the MSQL_USER when ** we're setup properly */ initDebug(1); netInitialise(); initServer(); (void)snprintf(path, MSQL_PATH_LEN, "%s", (char *)configGetCharEntry("general","pid_file")); pidFD = open(path, O_CREAT|O_TRUNC|O_RDWR, 0700); if (pidFD < 0) { perror("Error : Couldn't open PID file"); exit(1); } else { if (lockNonBlockingLock(pidFD) < 0) { printf("\nError : Cannot lock PID file!\n\n"); exit(1); } sprintf(pidBuf,"%d", (int)getpid()); write(pidFD, pidBuf, strlen(pidBuf) + 1); } /* ** Create the select lock file */ sprintf(path,"%s/msql.lock",INST_DIR); lockFD = open(path,O_CREAT|O_TRUNC|O_RDWR,0700); close(lockFD); /* ** Are we running as the right user? */ pwd = getpwuid(getuid()); if (!pwd) { printf("\nError! No username for our UID (%d)\n\n", (int)getuid()); exit(1); } uname = (char *)configGetCharEntry("general","msql_user"); if (strcmp(uname,pwd->pw_name) != 0) { pwd = getpwnam(uname); if (!pwd) { printf("\nError! Unknown username (%s)\n\n", uname); exit(1); } chown(path,pwd->pw_uid, pwd->pw_gid); chown("/proc/self/fd",pwd->pw_uid,pwd->pw_gid); if (setuid(pwd->pw_uid) < 0) { printf("\nError! Can't run as user '%s'\n\n",uname); exit(1); } } printf("\tServer running as user '%s'.\n",uname); printf("\tServer mode is %s.\n", configGetIntEntry("system","read_only")?"Read-Only":"Read/Write"); /* ** Ensure that the correct user owns the database files */ snprintf(path,MSQL_PATH_LEN, "%s/msqldb", (char *)configGetCharEntry("general","inst_dir")); if (stat(path,&sbuf) < 0) { printf("\nError! Can't stat '%s'\n\n",path); exit(1); } if (sbuf.st_uid != getuid()) { printf("\nError! '%s' is not owned by '%s'\n\n",path, pwd->pw_name); exit(1); } /* ** OK, on with the show */ umask(0); numCons=0; maxSock = 0; /* chdir(msqlHomeDir); */ tableCleanTmpDir(NULL);# ifdef BETA_RELEASE timeRemain = (863060000 + 60*24*60*60) - time(NULL); if (timeRemain < 0) { printf("\nThis Beta test release has expired!\n"); printf("Check out www.Hughes.com.au for a new release!\n\n"); exit(1); } else { printf("\n\tThis Beta test release expires in %d days.\n\n", (int)(timeRemain / (24*60*60))); }# endif chmod(path,0700); umask(0077); setupSignals(); (void)bzero(&children,sizeof(fd_set)); (void)bzero(conArray,sizeof(conArray)); maxChildSock = brokerStartChildren(&server,&children, argc,argv); strcpy(PROGNAME,"msqld"); aclLoadFile(1); msqlDebug0(MOD_GENERAL, "miniSQL debug mode. Waiting for connections.\n"); while(1) { /* ** Setup the read fd set */ FD_ZERO(&readFDs); if (IPsock >= 0) FD_SET(IPsock,&readFDs); if (UNIXsock >= 0) FD_SET(UNIXsock,&readFDs); brokerAddChildSockets(&readFDs); /* Wait for some action */ if(select((maxCons+globalServer->config.cacheDescriptors), &readFDs,0,0,0) < 0) { continue; } /* ** Is there a child notifying us? */ brokerCheckChildren(&readFDs); /* ** How about a new connection? Grab the lock so we ** can ensure the broker notification gets out before ** the new connection becomes active */ sock = 0; if (IPsock >= 0) { if (FD_ISSET(IPsock,&readFDs)) { sock = IPsock; } } if (UNIXsock >= 0) { if (FD_ISSET(UNIXsock,&readFDs)) { sock = UNIXsock; } } if (sock) { struct sockaddr_in cAddr; struct sockaddr dummy; size_t cAddrLen, dummyLen; bzero(&cAddr, sizeof(cAddr)); cAddrLen = sizeof(struct sockaddr_in); newSock = accept(sock, (struct sockaddr *)&cAddr, &cAddrLen); if(newSock < 0) { perror("Error in accept "); puntServer(-1); exit(1); } if (newSock > maxSock) maxSock = newSock; dummyLen = sizeof(struct sockaddr); if (getsockname(newSock,&dummy, &dummyLen) < 0) { perror("Error on new connection socket"); continue; } if (conArray[newSock].db) { if(conArray[newSock].db) { free(conArray[newSock].db); conArray[newSock].db = NULL; } if(conArray[newSock].host) { free(conArray[newSock].host); conArray[newSock].host = NULL; } if(conArray[newSock].user) { free(conArray[newSock].user); conArray[newSock].user = NULL; } } /* ** Are we over the connection limit */ numCons++; if (numCons > maxCons) { numCons--; netError(newSock,CON_COUNT_ERROR); shutdown(newSock,2); close(newSock); continue; } /* ** store the connection details */ msqlDebug1(MOD_GENERAL, "New connection received on %d\n", newSock); error = 0; if (sock == IPsock) { size_t addrLen; struct hostent *hp; addrLen = sizeof(struct sockaddr); getpeername(newSock, (struct sockaddr *) &remote, &addrLen); ipAddr = inet_ntoa(remote.sin_addr); if (ipAddr) { conArray[newSock].clientIP = strdup(ipAddr); } if (configGetIntEntry("system","host_lookup") == 1) { /* ** Validate remote host */ if(auth_hostname(&remote)) { netError(newSock, BAD_HOST_ERROR); error = 1; numCons--; shutdown(newSock,2); close(newSock); } /* ** Grab the hostname for later */ hp = (struct hostent *)gethostbyaddr( (char *)&remote.sin_addr, sizeof(remote.sin_addr), AF_INET); } else { hp = NULL; } if (!hp) { conArray[newSock].host = (char *) strdup("UNKNOWN_HOST"); msqlDebug0(MOD_GENERAL, "Host=UNKNOWN_HOST\n"); } else { conArray[newSock].host = (char *) strdup((char *)hp->h_name); msqlDebug1(MOD_GENERAL,"Host = %s\n", hp->h_name); } } else { conArray[newSock].host = NULL; conArray[newSock].clientIP = NULL; msqlDebug0(MOD_GENERAL,"Host = UNIX domain\n"); } conArray[newSock].connectTime = time(NULL); conArray[newSock].numQueries = 0; if (!error) { opt=1; setsockopt(newSock,SOL_SOCKET,SO_KEEPALIVE, (char *) &opt, sizeof(opt)); /*fcntl(newSock, F_SETFL, O_NONBLOCK);*/ snprintf(packet, PKT_LEN, "0:%d:%s\n", PROTOCOL_VERSION,SERVER_VERSION); netWritePacket(newSock); if (netReadPacket(newSock) <=0) { netError(newSock,HANDSHAKE_ERROR); shutdown(newSock,2); close(newSock); conArray[newSock].host = NULL; conArray[newSock].clientIP = NULL; } else { uname = (char *)strtok(packet,"\n"); msqlDebug1(MOD_GENERAL, "User = %s\n",uname); if(conArray[newSock].user) free(conArray[newSock].user); conArray[newSock].user = (char *) strdup(uname); brokerNotifyAllChildren(CMD_CLIENT_OPEN, -1, newSock, uname, NULL, NULL, 0, conArray[newSock].clientIP); netEndOfList(newSock); } } continue; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -