Changeset 6623 for trunk/tools
- Timestamp:
- Sep 2, 2001, 12:48:10 AM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/CmdQd/CmdQd.c
r6543 r6623 1 /* $Id: CmdQd.c,v 1. 2 2001-08-16 04:27:44bird Exp $1 /* $Id: CmdQd.c,v 1.3 2001-09-01 22:48:10 bird Exp $ 2 2 * 3 3 * Command Queue Daemon / Client. … … 193 193 194 194 195 typedef struct PathCache 196 { 197 char szPath[4096 - CCHMAXPATH * 3]; /* The path which this is valid for. */ 198 char szCurDir[CCHMAXPATH]; /* The current dir this is valid for. */ 199 char szProgram[CCHMAXPATH]; /* The program. */ 200 char szResult[CCHMAXPATH]; /* The result. */ 201 } PATHCACHE, *PPATHCACHE; 202 203 195 204 /******************************************************************************* 196 205 * Global Variables * … … 227 236 void signalhandler(int sig); 228 237 void Worker(void * iWorkerId); 238 char*WorkerArguments(char *pszArg, const char *pszzEnv, const char *pszCommand, char *pszCurDir, PPATHCACHE pPathCache); 239 char*fileNormalize(char *pszFilename, char *pszCurDir); 240 APIRET fileExist(const char *pszFilename); 229 241 int Submit(int rcIgnore); 230 242 int Wait(void); … … 311 323 } 312 324 313 return 0;325 //return 0; 314 326 } 315 327 … … 699 711 void signalhandler(int sig) 700 712 { 701 shrmemFree(); 702 exit(-42); 713 sig = sig; 714 shrmemFree(); 715 exit(-42); 703 716 } 704 717 … … 711 724 void Worker(void * iWorkerId) 712 725 { 726 PATHCACHE PathCache; 727 memset(&PathCache, 0, sizeof(PathCache)); 728 713 729 while (!DosWaitEventSem(hevJobQueue, SEM_INDEFINITE_WAIT)) 714 730 { … … 758 774 * Redirect output and start process. 759 775 */ 760 sprintf(szArg, "%s\t /C \"%s\"\n", getenv("COMSPEC"), pJob->JobInfo.szCommand);761 *strchr(szArg, '\t') = '\0';776 WorkerArguments(szArg, &pJob->JobInfo.szzEnv, &pJob->JobInfo.szCommand[0], 777 &pJob->JobInfo.szCurrentDir[0], &PathCache); 762 778 rc = DosCreatePipe(&hPipeR, &hPipeW, sizeof(pJobOutput->szOutput) - 1); 763 779 if (rc) … … 912 928 } 913 929 } 930 iWorkerId = iWorkerId; 931 } 932 933 934 /** 935 * Builds the input to DosExecPgm. 936 * Will execute programs directly and command thru the shell. 937 * 938 * @returns pszArg. 939 * @param pszArg Arguments to DosExecPgm.(output) 940 * Assumes that the buffer is large enought. 941 * @param pszzEnv Pointer to environment block. 942 * @param pszCommand Command to execute. 943 * @param pszCurDir From where the command is to executed. 944 * @param pPathCache Used to cache the last path, executable, and the search result. 945 */ 946 char *WorkerArguments(char *pszArg, const char *pszzEnv, const char *pszCommand, char *pszCurDir, PPATHCACHE pPathCache) 947 { 948 BOOL fCMD = FALSE; 949 const char *psz; 950 const char *psz2; 951 char * pszW; 952 char ch; 953 int cch; 954 APIRET rc; 955 956 /* 957 * Check if this is multiple command separated by either &, && or |. 958 * Currently ignoring quotes for this test. 959 */ 960 if ( strchr(pszCommand, '&') 961 || strchr(pszCommand, '|')) 962 { 963 strcpy(pszArg, "cmd.exe"); /* doesn't use comspec, just defaults to cmd.exe in all cases. */ 964 fCMD = TRUE; 965 psz2 = pszCommand; /* start of arguments. */ 966 } 967 else 968 { 969 char chEnd = ' '; 970 971 /* 972 * Parse out the first name. 973 */ 974 for (psz = pszCommand; *psz == '\t' || *psz == ' ';) //strip(,'L'); 975 psz++; 976 if (*psz == '"' || *psz == '\'') 977 chEnd = *psz++; 978 psz2 = psz; 979 if (chEnd == ' ') 980 { 981 while ((ch = *psz) != '\0' && ch != ' ' && ch != '\t') 982 psz++; 983 } 984 else 985 { 986 while ((ch = *psz) != '\0' && ch != chEnd) 987 psz++; 988 } 989 *pszArg = '\0'; 990 strncat(pszArg, psz2, psz - psz2); 991 psz2 = psz+1; /* start of arguments. */ 992 } 993 994 995 /* 996 * Resolve the executable name if not qualified. 997 * NB! We doesn't fully support references to other driveletters yet. (TODO/BUGBUG) 998 */ 999 /* correct slashes */ 1000 pszW = pszArg; 1001 while ((pszW = strchr(pszW, '//')) != NULL) 1002 *pszW++ = '\\'; 1003 1004 /* make sure it ends with .exe */ 1005 pszW = pszArg + strlen(pszArg) - 1; 1006 while (pszW > pszArg && *pszW != '.' && *pszW != '\\') 1007 pszW--; 1008 if (*pszW != '.') 1009 strcat(pszArg, ".exe"); 1010 1011 if (pszArg[1] != ':' || *pszArg == *pszCurDir) 1012 { 1013 rc = -1; /* indicate that we've not found the file. */ 1014 1015 /* relative path? - expand it */ 1016 if (strchr(pszArg, '\\') || pszArg[1] == ':') 1017 { /* relative path - expand it and check for file existence */ 1018 fileNormalize(pszArg, pszCurDir); 1019 rc = fileExist(pszArg); 1020 } 1021 else 1022 { /* Search path. */ 1023 const char *pszPath = pszzEnv; 1024 while (*pszPath != '\0' && strncmp(pszPath, "PATH=", 5)) 1025 pszPath += strlen(pszPath) + 1; 1026 1027 if (pszPath && *pszPath != '\0') 1028 { 1029 /* check cache */ 1030 if ( !strcmp(pPathCache->szProgram, pszArg) 1031 && !strcmp(pPathCache->szPath, pszPath) 1032 && !strcmp(pPathCache->szCurDir, pszCurDir) 1033 ) 1034 { 1035 strcpy(pszArg, pPathCache->szResult); 1036 rc = fileExist(pszArg); 1037 } 1038 1039 if (rc) 1040 { /* search path */ 1041 char szResult[CCHMAXPATH]; 1042 rc = DosSearchPath(SEARCH_IGNORENETERRS, pszPath, pszArg, &szResult[0] , sizeof(szResult)); 1043 if (!rc) 1044 { 1045 strcpy(pszArg, szResult); 1046 1047 /* update cache */ 1048 strcpy(pPathCache->szProgram, pszArg); 1049 strcpy(pPathCache->szPath, pszPath); 1050 strcpy(pPathCache->szCurDir, pszCurDir); 1051 strcpy(pPathCache->szResult, szResult); 1052 } 1053 } 1054 } 1055 } 1056 } 1057 /* else nothing to do - assume full path (btw. we don't have the current dir for other drives anyway :-) */ 1058 else 1059 rc = !fCMD ? fileExist(pszArg) : NO_ERROR; 1060 1061 /* In case of error use CMD */ 1062 if (rc && !fCMD) 1063 { 1064 strcpy(pszArg, "cmd.exe"); /* doesn't use comspec, just defaults to cmd.exe in all cases. */ 1065 fCMD = TRUE; 1066 psz2 = pszCommand; /* start of arguments. */ 1067 } 1068 1069 1070 /* 1071 * Complete the argument string. 1072 * --- 1073 * szArg current holds the command. 1074 * psz2 points to the first parameter. (needs strip(,'L')) 1075 */ 1076 while ((ch = *psz2) != '\0' && (ch == '\t' || ch == ' ')) 1077 psz2++; 1078 1079 pszW = pszArg + strlen(pszArg) + 1; 1080 cch = strlen(psz2); 1081 if (!fCMD) 1082 { 1083 memcpy(pszW, psz2, ++cch); 1084 pszW[cch] = '\0'; 1085 } 1086 else 1087 { 1088 strcpy(pszW, "/C \""); 1089 pszW += strlen(pszW); 1090 memcpy(pszW, psz2, cch); 1091 memcpy(pszW + cch, "\"\0", 3); 1092 } 1093 1094 return pszArg; 1095 } 1096 1097 1098 1099 /** 1100 * Normalizes the path slashes for the filename. It will partially expand paths too. 1101 * @returns pszFilename 1102 * @param pszFilename Pointer to filename string. Not empty string! 1103 * Much space to play with. 1104 * @remark (From fastdep.) 1105 */ 1106 char *fileNormalize(char *pszFilename, char *pszCurDir) 1107 { 1108 char * psz; 1109 int aiSlashes[CCHMAXPATH/2]; 1110 int cSlashes; 1111 int i; 1112 1113 /* 1114 * Init stuff. 1115 */ 1116 for (i = 1, cSlashes; pszCurDir[i] != '\0'; i++) 1117 { 1118 if (pszCurDir[i] == '/') 1119 pszCurDir[i] = '\\'; 1120 if (pszCurDir[i] == '\\') 1121 aiSlashes[cSlashes++] = i; 1122 } 1123 if (pszCurDir[i-1] != '\\') 1124 { 1125 aiSlashes[cSlashes] = i; 1126 pszCurDir[i++] = '\\'; 1127 pszCurDir[i] = '\0'; 1128 } 1129 1130 1131 /* expand path? */ 1132 pszFilename = psz; 1133 if (pszFilename[1] != ':') 1134 { /* relative path */ 1135 int iSlash; 1136 char szFile[CCHMAXPATH]; 1137 char * psz = szFile; 1138 1139 strcpy(szFile, pszFilename); 1140 iSlash = *psz == '\\' ? 1 : cSlashes; 1141 while (*psz != '\0') 1142 { 1143 if (*psz == '.' && psz[1] == '.' && psz[2] == '\\') 1144 { /* up one directory */ 1145 if (iSlash > 0) 1146 iSlash--; 1147 psz += 3; 1148 } 1149 else if (*psz == '.' && psz[1] == '\\') 1150 { /* no change */ 1151 psz += 2; 1152 } 1153 else 1154 { /* completed expantion! */ 1155 strncpy(pszFilename, pszCurDir, aiSlashes[iSlash]+1); 1156 strcpy(pszFilename + aiSlashes[iSlash]+1, psz); 1157 break; 1158 } 1159 } 1160 } 1161 /* else: assume full path */ 1162 1163 return psz; 1164 } 1165 1166 /** 1167 * Checks if a given file exist. 1168 * @returns 0 if the file exists. (NO_ERROR) 1169 * 2 if the file doesn't exist. (ERROR_FILE_NOT_FOUND) 1170 * @param pszFilename Name of the file to check existance for. 1171 */ 1172 APIRET fileExist(const char *pszFilename) 1173 { 1174 FILESTATUS3 fsts3; 1175 return DosQueryPathInfo(pszFilename, FIL_STANDARD, &fsts3, sizeof(fsts3)); 914 1176 } 915 1177 … … 923 1185 int Submit(int rcIgnore) 924 1186 { 925 int i;926 1187 int cch; 927 1188 int rc; … … 960 1221 shrmemFree(); 961 1222 return -1; 1223 } 1224 if (*psz == '"' && psz[cch-2] == '"') /* remove start & end quotes if any */ 1225 { 1226 cch--; 1227 psz++; 962 1228 } 963 1229 memcpy(&pShrMem->u1.Submit.szCommand[0], psz, cch); … … 1081 1347 { 1082 1348 int rc; 1083 rc = DosAllocSharedMem((PPVOID) &pShrMem,1349 rc = DosAllocSharedMem((PPVOID)(PVOID)&pShrMem, 1084 1350 SHARED_MEM_NAME, 1085 1351 SHARED_MEM_SIZE, … … 1151 1417 { 1152 1418 int rc; 1153 ULONG ulDummy; 1154 rc = DosGetNamedSharedMem((PPVOID) &pShrMem,1419 1420 rc = DosGetNamedSharedMem((PPVOID)(PVOID)&pShrMem, 1155 1421 SHARED_MEM_NAME, 1156 1422 PAG_READ | PAG_WRITE);
Note:
See TracChangeset
for help on using the changeset viewer.